Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

351
Visualizações
Python Celery sincronización de cronjob inconsistente para la programación de tareas con la función ahora

La situación

Tengo una tarea de apio que estoy ejecutando en una zona horaria diferente para cada cliente.

Básicamente, para cada cliente en mi base de datos, obtengo la zona horaria y luego configuro la tarea de apio de esta manera.

 'schedule': crontab(minute=30, hour=14, nowfun=self.now_function)

Básicamente, lo que quiero es que la tarea se ejecute a las 14:30, en la zona horaria del cliente. De ahí la función now_.

Mi now_function solo obtiene la hora actual con la zona horaria del cliente.

 def now_function(self): """ return the now function for the task this is used to compute the time a task should be scheduled for a given customer """ return datetime.now(timezone(self.customer.c_timezone))

Qué está pasando

Obtengo inconsistencias en el tiempo de ejecución de la tarea, a veces se ejecutan a la hora prevista, así que digamos a las 14:30 en la zona horaria del cliente, si la zona horaria es America/Chicago , se ejecuta a las 20:30 y ese es mi comportamiento esperado. .

Algunos otros días, funciona a las 14:30, que es la hora en UTC.

Estoy rastreando para ver si hay un patrón en el día en que la tarea se ejecuta en el momento correcto y el día en que las tarjetas se ejecutan en el momento incorrecto.

información adicional

He intentado esto en apio 4.4.2 y 5.xx pero todavía tiene el mismo comportamiento.

Aquí está mi configuración de apio.

 CELERY_REDIS_SCHEDULER_URL = redis_instance_url logger.debug("****** CELERY_REDIS_SCHEDULER_URL: ", CELERY_REDIS_SCHEDULER_URL) logger.debug("****** environment: ", environment) redbeat_redis_url = CELERY_REDIS_SCHEDULER_URL broker_url = CELERY_REDIS_SCHEDULER_URL result_backend = CELERY_REDIS_SCHEDULER_URL task_serializer = 'pickle' result_serializer = 'pickle' accept_content = ['pickle'] enable_utc = False task_track_started = True task_send_sent_event = True

Puede notar que enable_utc está establecido en False .

  • Estoy usando la instancia de Redis de AWS para ejecutar mi tarea.
  • Estoy usando el programador RedBeatScheduler de este paquete para programar mis tareas.

Si alguien ha tenido este problema o me puede ayudar a reproducirlo, le estaré muy agradecido.

Otras ediciones:

  • Tengo otro cron para el mismo trabajo al mismo tiempo pero funcionando semanal y mensualmente pero están funcionando perfectamente.
 weekly_schedule : crontab(minute=30, hour=14, nowfun=self.now_function, day_of_week=1) monthly_schedule : crontab(minute=30, hour=14, nowfun=self.now_function, day_of_month=1)

Proyecto de muestra

Aquí hay un proyecto de muestra en GitHub si desea ejecutar y reproducir el problema.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

El codificador y decodificador de RedBeat no son compatibles nowfun .
Código fuente: https://github.com/sibson/redbeat/blob/e6d72e2/redbeat/decoder.py#L94-L102
El comportamiento que ve se describió anteriormente: sibson/redbeat#192 (comentario 756397651)

Puede subclasificar y reemplazar RedBeatJSONDecoder y RedBeatJSONEncoder .

Dado que nowfun tiene que ser JSON serializable, solo podemos admitir algunos casos especiales,
por ejemplo nowfun=partial(datetime.now, tz=pytz.timezone(self.customer.c_timezone))

 from datetime import datetime from functools import partial from celery.schedules import crontab import pytz from pytz.tzinfo import DstTzInfo from redbeat.decoder import RedBeatJSONDecoder, RedBeatJSONEncoder class CustomJSONDecoder(RedBeatJSONDecoder): def dict_to_object(self, d): if '__type__' not in d: return d objtype = d.pop('__type__') if objtype == 'crontab': if d.get('nowfun', {}).get('keywords', {}).get('zone'): d['nowfun'] = partial(datetime.now, tz=pytz.timezone(d.pop('nowfun')['keywords']['zone'])) return crontab(**d) d['__type__'] = objtype return super().dict_to_object(d) class CustomJSONEncoder(RedBeatJSONEncoder): def default(self, obj): if isinstance(obj, crontab): d = super().default(obj) if 'nowfun' not in d and isinstance(obj.nowfun, partial) and obj.nowfun.func == datetime.now: zone = None if obj.nowfun.args and isinstance(obj.nowfun.args[0], DstTzInfo): zone = obj.nowfun.args[0].zone elif isinstance(obj.nowfun.keywords.get('tz'), DstTzInfo): zone = obj.nowfun.keywords['tz'].zone if zone: d['nowfun'] = {'keywords': {'zone': zone}} return d return super().default(obj)

Reemplace las clases en redbeat.schedulers :

 from redbeat import schedulers schedulers.RedBeatJSONDecoder = CustomJSONDecoder schedulers.RedBeatJSONEncoder = CustomJSONEncoder
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda