2017-01-23 6 views
1

Ich arbeite an Sellerie für hohe Verfügbarkeit machen Ich habe die django_celery Projekt und diese Gabel von celery gespalten, um die Anpassungen, die ich brauche. Der Sellerie Link zeigt die Änderungen an der beat.py das den folgenden Code verwendet:So fügen Sie ein benutzerdefiniertes Modell zu Django_Sellery

ich dieses Lock-Modell hinzugefügt haben models.py Datei django_celery und konnte ganz gut migrieren:

from django.db import models 

@python_2_unicode_compatible 
class Lock(models.Model): 
    name = models.CharField(max_length=127, unique=True) 
    created = models.DateTimeField(auto_now=True) 

    class Meta: 
     verbose_name_plural = _('locks') 

    def __str__(self): 
     return self.name 

In

from djcelery.models import Lock 
from datetime import datetime, timedelta 
from django.db import transaction, IntegrityError 


class Locked(object): 
    """A context manager to add a distributed mutex.""" 

    def __init__(self, name, timeout): 
     self.name = name 
     self.lock = None 
     self.timeout = timeout 

    def __enter__(self): 
     # first delete any expired locks 
     expired = datetime.utcnow() - timedelta(seconds=self.timeout) 
     Lock.objects.filter(name=self.name, created__lte=expired).delete() 
     # then try to get the lock 
     try: 
      Lock(name=self.name).save() 
     except IntegrityError: 
      transaction.rollback() 
      raise LockError('Could not acquire lock: {0}'.format(self.name)) 

    def __exit__(self, *args): 
     Lock.objects.filter(name=self.name).delete() 


class LockError(Exception): 
    """Exception thrown when the requested lock already exists.""" 

    pass 

mit diesen Änderungen ich in der Lage bin die folgenden Befehle ausführen: Sellerie im utils Ordner diese locked.py Datei ich habe hinzugefügt

celery worker 
python manage.py runserver 
python manage.py shell 

I gibt arrises wenn ich versuche, den Scheduler zu laufen:

celery beat 

ich die folgende Fehlermeldung erhalten:

Traceback (most recent call last): 
    File "venv/bin/celery", line 11, in <module> 
    load_entry_point('celery', 'console_scripts', 'celery')() 
    File "/venv/src/celery/celery/__main__.py", line 30, in main 
    main() 
    File "/venv/src/celery/celery/bin/celery.py", line 81, in main 
    cmd.execute_from_commandline(argv) 
    File "/venv/src/celery/celery/bin/celery.py", line 793, in execute_from_commandline 
    super(CeleryCommand, self).execute_from_commandline(argv))) 
    File "/venv/src/celery/celery/bin/base.py", line 311, in execute_from_commandline 
    return self.handle_argv(self.prog_name, argv[1:]) 
    File "/venv/src/celery/celery/bin/celery.py", line 785, in handle_argv 
    return self.execute(command, argv) 
    File "/venv/src/celery/celery/bin/celery.py", line 717, in execute 
    ).run_from_argv(self.prog_name, argv[1:], command=argv[0]) 
    File "/venv/src/celery/celery/bin/base.py", line 315, in run_from_argv 
    sys.argv if argv is None else argv, command) 
    File "/venv/src/celery/celery/bin/base.py", line 377, in handle_argv 
    return self(*args, **options) 
    File "/venv/src/celery/celery/bin/base.py", line 274, in __call__ 
    ret = self.run(*args, **kwargs) 
    File "/venv/src/celery/celery/bin/beat.py", line 72, in run 
    beat = partial(self.app.Beat, 
    File "/venv/lib/python2.7/site-packages/kombu/utils/__init__.py", line 325, in __get__ 
    value = obj.__dict__[self.__name__] = self.__get(obj) 
    File "/venv/src/celery/celery/app/base.py", line 572, in Beat 
    return self.subclass_with_self('celery.apps.beat:Beat') 
    File "/venv/src/celery/celery/app/base.py", line 504, in subclass_with_self 
    Class = symbol_by_name(Class) 
    File "/venv/lib/python2.7/site-packages/kombu/utils/__init__.py", line 96, in symbol_by_name 
    module = imp(module_name, package=package, **kwargs) 
    File "/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module 
    __import__(name) 
    File "/venv/src/celery/celery/apps/beat.py", line 19, in <module> 
    from celery import VERSION_BANNER, platforms, beat 
    File "/venv/src/celery/celery/beat.py", line 35, in <module> 
    from .utils.locked import Locked, LockError 
    File "/venv/src/celery/celery/utils/locked.py", line 1, in <module> 
    from djcelery.models import Lock 
    File "/venv/src/django-celery/djcelery/models.py", line 30, in <module> 
    class TaskMeta(models.Model): 
    File "/venv/lib/python2.7/site-packages/django/db/models/base.py", line 105, in __new__ 
    app_config = apps.get_containing_app_config(module) 
    File "/venv/lib/python2.7/site-packages/django/apps/registry.py", line 237, in get_containing_app_config 
    self.check_apps_ready() 
    File "/venv/lib/python2.7/site-packages/django/apps/registry.py", line 124, in check_apps_ready 
    raise AppRegistryNotReady("Apps aren't loaded yet.") 
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. 

ich djcelery in meinem INSTALLED_APPS haben Einstellung, damit ich weiß nicht, was los ist an diesem Punkt?

Antwort

0

Sellerie wird oft mit Django verwendet und ist kompatibel mit Django, ist aber nicht inhärent eine Django-Anwendung. Die Änderungen, die Sie vorgenommen haben, sind so, dass bei Ausführung von Django-Modelle geladen werden. Um die Modelle verwenden zu können, müssen die Anwendungen zuerst initialisiert werden. Die Standardmethode dafür ist, django.setup()nach aufzurufen, die Dinge eingestellt haben, damit Djangos Code die Django-Einstellungen finden kann. Es könnte sein, so etwas wie:

import os 
import django 

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") 
django.setup() 

Sie müssen project.settings den eigentlichen Modulnamen ändern, die die Einstellungen enthalten.

1

Sie App-Instanz angeben, müssen für den Sellerie Befehl

-A APP, --app=APP app instance to use (e.g. module.attr_name)

Zum Beispiel zu verwenden, wenn i Struktur

pybilling 
- pybilling 
    - celeryconfig.py 

dann sollte ich Sellerie Schlag mit dem Befehl

celery --app pybilling.celeryconfig:app beat 
starten

Hier ist der Inhalt von selleryconfig.py

from __future__ import absolute_import 

import os 

from celery import Celery 

# set the default Django settings module for the 'celery' program. 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pybilling.settings') 

from django.conf import settings # noqa 

app = Celery('pybilling') 

# Using a string here means the worker will not have to 
# pickle the object when using Windows. 
app.config_from_object('django.conf:settings') 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 
Verwandte Themen