2012-06-01 5 views
1

У меня есть вид в моем проекте django, который срабатывает с задачей сельдерея. Задача сельдерея запускает несколько заданий по карте/сокращению с помощью подпроцесса/ткани, а результаты задания hadoop хранятся на диске --- ничто фактически не хранится в базе данных. После того, как работа Hadoop была завершена, задача сельдерей посылает сигнал Джанго, что это сделано, что-то вроде этого:«./manage.py запускает сервер» перезапускается, когда запущены карты сельдерея/сокращения задач; Иногда возникает ошибка с inner_run

# tasks.py 
from models import MyModel 
import signals 

from fabric.operations import local 

from celery.task import Task 

class Hadoopification(Task): 
    def run(self, my_model_id, other_args): 
     my_model = MyModel.objects.get(pk=my_model_id) 
     self.hadoopify_function(my_model, other_args) 
     signals.complete_signal.send(
      sender=self, 
      my_model_id=my_model_id, 
      complete=True, 
     ) 

    def hadoopify_function(self, my_model, other_args): 
     local("""hadoop jar /usr/lib/hadoop/hadoop-streaming.jar -D mapred.reduce.tasks=0 -file hadoopify.py -mapper "parse_mapper.py 0 0" -input /user/me/input.csv -output /user/me/output.csv""") 

Что действительно сбивает с толку меня является то, что Джанго runserver является перегрузки когда задача сельдерей как будто я изменил какой-то код где-то в проекте django (чего у меня нет, могу вас заверить!). Время от времени это даже вызывает ошибки в команде runerver, где я вижу вывод, как показано ниже, до перезагрузки команды runerver и снова в порядке (обратите внимание: это сообщение об ошибке очень похоже на problem described here).

Unhandled exception in thread started by <function inner_run at 0xa18cd14> 
Error in sys.excepthook: 
Traceback (most recent call last): 
    File "/usr/lib/python2.6/dist-packages/apport_python_hook.py", line 48, in apport_excepthook 
    if not enabled(): 
TypeError: 'NoneType' object is not callable 

Original exception was: 
Traceback (most recent call last): 
    File "/home/rdm/Biz/Projects/Daegis/Server_Development/tar/env/lib/python2.6/site-packages/django/core/management/commands/runserver.py", line 60, in inner_run 
    run(addr, int(port), handler) 
    File "/home/rdm/Biz/Projects/Daegis/Server_Development/tar/env/lib/python2.6/site-packages/django/core/servers/basehttp.py", line 721, in run 
    httpd.serve_forever() 
    File "/usr/lib/python2.6/SocketServer.py", line 224, in serve_forever 
    r, w, e = select.select([self], [], [], poll_interval) 
AttributeError: 'NoneType' object has no attribute 'select' 

Я сузили проблему вниз, когда вызовы сделаны Hadoop путем замены local("""hadoop ...""") с local("ls"), который не вызывает каких-либо проблем с перегрузкой в ​​Джанго runserver. В коде hadoop нет ошибок - он отлично работает сам по себе, когда его не вызывают сельдерей.

Любая идея о том, что может быть причиной этого?

ответ

1

Существует некоторая дискуссия об этом на ткани GitHub странице here, here и here. Другой вариант возникновения ошибки является использование диспетчера настройки контекста:

from fabric.api import settings 

class Hadoopification(Task): 
    ... 
    def hadoopify_function(self, my_model, other_args): 
     with settings(warn_only=True): 
      result = local(...) 
     if result.failed: 
      # access result.return_code, result.stdout, result.stderr 
      raise UsefulException(...) 

Это имеет то преимущество, что обеспечивает доступ к коду возврата и все другие атрибуты на результат.

+0

Мне это нравится еще лучше! теперь мне нужно написать только полезное исключение :) – dino

0

Я предполагаю, что есть какое-то столкновение на имя Task как в сельдерее, так и в ткани. Я бы предложил использовать что-то еще:

import celery 
class Hadoopification(celery.task.Task): 
    ... 

И старайтесь избегать дальнейших столкновений, если эта догадка хорошая.

Но на самом деле, местная ткань является довольно скудной, и по существу это просто подпроцесс.Popen, который вы могли бы попробовать вызвать raw, чтобы также выделить что-либо, кроме python stdlib.

+0

столкновения были интересной идеей. я заглянул в это, только запустив один процесс сельдерея за раз, и это не решило проблему. спасибо за вашу помощь! – dino

2

Итак, после того, как я начал копаться в исходном коде ткани, я пришел к выводу, что django перезагружается, потому что моя задача сельдерея, выполняемая внутри команды fabric.operations.local, терпит неудачу (что трудно обнаружить в файле hadoop output puke -fest). Когда команда fabric.operations.local терпит неудачу, fabric issues a sys.exit, из-за чего сельдерей умирает и django пытается и перезагружается. Эта ошибка может быть обнаружена ловя SystemExit в рамках задач Hadoop, как это:

class Hadoopification(Task): 
    def run(self, my_model_id, other_args): 
     my_model = MyModel.objects.get(pk=my_model_id) 
     self.hadoopify_function(my_model, other_args) 
     signals.complete_signal.send(
      sender=self, 
      my_model_id=my_model_id, 
      complete=True, 
     ) 

    def hadoopify_function(self, my_model, other_args): 
     try: 
      local("""hadoop jar /usr/lib/hadoop/hadoop-streaming.jar -D mapred.reduce.tasks=0 -file hadoopify.py -mapper "parse_mapper.py 0 0" -input /user/me/input.csv -output /user/me/output.csv""") 
     except SystemExit, e: 
      # print some useful debugging information about exception e here! 
      raise