У нас есть некоторый код параллельной обработки, построенный на базе Pebble, он довольно долго работал надежно, но мы, кажется, натолкнулись на какой-то странный крайний случай.
На основе трассировки исключений (и простой код, питающий его) Я подозреваю, что это на самом деле ошибка в Pebble, но кто знает.
Код, заполняющий пул процессов, довольно тривиален:
pool = ProcessPool(max_workers=10, max_tasks=10)
for path in filepaths:
try:
future = pool.schedule(function=self.analyse_file, args(path), timeout=30)
future.add_done_callback(self.process_result)
exception Exception as e:
print("Exception fired:" + e) # NOT where the exception is firing
pool.close()
pool.join()
Итак, по сути, мы планируем запуск нескольких вещей, закрываем пул и ждем, пока пул завершит запланированные задачи. ПРИМЕЧАНИЕ: исключение не генерируется в расписании l oop, оно запускается ПОСЛЕ того, как мы называем join()
.
Это трассировка стека исключений:
Traceback (most recent call last):
File "/home/user/.pyenv/versions/3.6.0/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/home/user/.pyenv/versions/3.6.0/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/home/user/.pyenv/versions/scrapeapp/lib/python3.6/site-packages/pebble/pool/process.py", line 150, in task_scheduler_loop
pool_manager.schedule(task)
File "/home/user/.pyenv/versions/scrapeapp/lib/python3.6/site-packages/pebble/pool/process.py", line 198, in schedule
self.worker_manager.dispatch(task)
File "/home/user/.pyenv/versions/scrapeapp/lib/python3.6/site-packages/pebble/pool/process.py", line 327, in dispatch
self.pool_channel.send(WorkerTask(task.id, task.payload))
File "/home/user/.pyenv/versions/scrapeapp/lib/python3.6/site-packages/pebble/pool/channel.py", line 66, in send
return self.writer.send(obj)
File "/home/user/.pyenv/versions/3.6.0/lib/python3.6/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/home/user/.pyenv/versions/3.6.0/lib/python3.6/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
RuntimeError: dictionary changed size during iteration
Я думаю, это должно быть какое-то странное состояние гонки, поскольку код будет работать безупречно на некоторых наборах данных, но не работать в том, что кажется случайной точкой в другом наборе данных.
Мы использовали pebble 4.3.1, когда мы впервые запустили в проблему (ту же версию, что была у нас с самого начала), попытался обновить до 4.5.0, без изменений.
Кто-нибудь сталкивался с подобными проблемами с Pebble в прошлом? Если да, то что ты исправил?