2017-06-13 2 views
2

J'ai une lourde classe de bibliothèque externe qui prend du temps pour s'initialiser et consomme beaucoup de mémoire. Je veux le créer une fois par instance de la tâche, au minimum.est Celery Tâche initialisée par chaque processus de travail, ou une fois par application?

class NlpTask(Task): 
    def __init__(self): 
     print('initializing NLP parser') 
     self._parser = nlplib.Parser() 
     print('done initializing NLP parser') 

    @property 
    def parser(self): 
     return self._parser 

@celery.task(base=NlpTask) 
def my_task(arg): 
    x = my_task.parser.process(arg) 
    # etc. 

Céleri commence 32 processus de travail, donc j'attendre les "initializing ... done" 32 fois l'impression, comme je suppose qu'une instance de tâche est créé pour chaque travailleur. Étonnamment, je reçois l'impression une fois. Qu'est-ce qui se passe réellement là? Merci.

Répondre

1

Votre NlpTask s'initialise une fois lorsqu'il est enregistré auprès du travailleur.

Si vous avez deux tâches comme

@celery.task(base=NlpTask) 
def foo(arg): 
    pass 


@celery.task(base=NlpTask) 
def bar(arg): 
    pass 

Puis, quand vous commencez un travailleur, vous verrez 2 initialisations.

Si vous souhaitez l'initialiser une fois pour chaque travailleur, vous pouvez utiliser le signal worker_process_init. Maintenant, lorsque vous démarrez un worker, vous verrez que le processus est appelé par chaque processus une seule fois.

+0

c'est mon point - je m'attendrais une fois par travailleur, et il semble qu'une fois par instance de céleri. J'ai édité la question – davka

+0

@davka Mis à jour la réponse. – ChillarAnand