Ed1. Тут не согласен, иерархия исключений такова:
ОК, принимая во внимание ваши ограничения моя критика и пожелания такая:
1. Имея три разных исключения вы создаете проблемы на верхнем уровне. Их же нужно будет ловить потом. Проще бросать одно исключение с информативными сообщениями.
2. Не уверен, что это именно имелось в виду под кривым логированием, но на всякий случай напишу: настройка логирования в классе BaseProcessing не очень красиво выглядит. Лучше конфигурить его отдельно. Вот, почитайте здесь как это можно сделать: http://www.python.su/forum/viewtopic.ph … 190#p59190
3. Я ничего не имею против декоратора with_timeout как такового. Мне не нравится реализация с тремя уровнями замыканий. Декораторы с аргументами лучше делать через классы, по-моему. Вот пример: http://www.artima.com/weblogs/viewpost. … ead=240845
4. Можно пронаследовать BaseProcessing от Pool, по-моему так код будет чище. Это типа такой пул с функцией диспетчеризации. Можно и обозвать его соответственно.
5. Какой смысл в handlers = None? Кто процессить-то будет, если у нас такие дефолты?
6. Насчет жесткого вызова spawn я не понял. По-моему тут наоборот любой набор параметров можно использовать. Первые два в задаче - приоритет и название, они пропускаются. Остальные - любые.
ProcessingError(Exception) - верхний уровень исключений. Исключения только относящиеся к самому BaseProcessing
HandlerError(ProcessingError) - различного рода ошибки связанные с обработчиком зачачи.
HandlerTimeout(HandlerError) - конкретная ошибка обработчика
Это пока единственное исключение брошенное в классе:
if handler is None:
raise HandlerError, \
"Required handler for task {} not defined".format(task[1])
ProcessingError(Exception)
HandlerGeneralError(ProcessingError)
HandlerTimeoutError(HandlerError)
HandlerMissingError(HandlerError)
?
2. Да жестко заданное логгирование у меня хромает, я смотрел как вы настраивали в своем примере http://pastebin.com/M24z5RsV и поправил у себя
3. Спасибо, ушел читать. Декоратор правда все равно получился бесполезный у меня :( т.к. если заставить его бросать исключение то словить его никто не может, оно выпадает “где-то” в гринлете, выводится в консоль но никак не ловится, оно и понятно почему. Поэтому таймаут обработку наверное нужно делать в самом обработчике либо делать заточенный декоратор под определенную задачу, чтобы не повторять себя. Это пока для меня черная магия.
4. Идея лежала на поверхности и я ее не заметил, спасибо.
5. handlers=None нужен для определения своих обработчиков. Это может быть не python waу, представим ситуацию когда в RssProcessing мне нужно переопределить image_handler малой кровью, я могу:
а) processing.image_handler = some_fnc
b) processing = RssProcessing(handlers={'image_handler': some_fnc})
А при запуске задачи следуйщий код определит кто будет обработчиком:
handler = getattr(self, task[1], None)
if task[1] in self.handlers:
handler = self.handlers[task[1]]
6. Нет мне не очень нравится как потом выглядят сигнатуры обработчиков, хотя может я просто привередничаю :)