Задача Django celery повторяется каждый час, ее следует выполнять только один раз в день
Программа course_message_schedule_task
запускается каждый день в 04:00:00. В нем мы регистрируем course_message_send_task
для запуска в 10:00:00 каждый день.
Однако, если вы посмотрите на журнал ниже, course_message_send_task
повторяется каждый час с 04:00:00 до 10:00:00.
(задача businessletter_send_task повторяется тем же способом.)
Это должно выполняться один раз в день, я не знаю, почему это задание повторяется.
настройки
# ...
settings.CELERYBEAT_SCHEDULE.update(
{
"send-emon-data-task": {
"task": "klms.emon_api_task.send_emon_data_task",
"schedule": crontab(hour="*", minute="0"),
"kwargs": {},
},
"course-message-schedule-task": {
"task": "klms.tasks.course_message_schedule_task",
"schedule": crontab(hour="4", minute="0"),
"kwargs": {},
},
"create-coursereport-task": {
"task": "klms.tasks.create_coursereport_task",
"schedule": crontab(hour="5", minute="0"),
"kwargs": {},
},
"businessletter-schedule-task": {
"task": "klms.tasks.businessletter_schedule_task",
"schedule": crontab(hour="6", minute="0"),
"kwargs": {},
},
}
)
# ...
задачи
@shared_task(base=LoggedPersistOnFailureTask, default_retry_delay=30)
def course_message_send_task():
"""
today's messages
"""
# default 10:00:00
time_part = settings.COURSE_MESSAGE_SENDING_SCHEDULE_TIME.split(":")
schedule_time = localtime().replace(
hour=int(time_part[0]),
minute=int(time_part[1]),
second=int(time_part[2]),
microsecond=0,
)
# filter
ids = list(
MessageService.objects.filter(schedule=schedule_time)
.exclude(
status__isnull=False,
)
.values_list("id", flat=True)
)
# send!
MessageService.status_handler(ids)
@shared_task(base=LoggedPersistOnFailureTask, default_retry_delay=30)
def course_message_schedule_task():
"""
schedule course messages
"""
enrollmentinfo = (
EnrollmentInfo.objects.message_context()
.filter(
# 학습 시작일, n주차, 종료일, 종료 다음날
Q(days_from_study_start=1)
| Q(ordinal_in_week=1)
| Q(days_to_study_end__in=[0, -1]),
# 종료되기 전 과정
days_to_study_end__gt=-1,
)
.exclude(email_notification=False, text_notification=False)
.distinct()
)
messages = []
# default 10:00:00
time_part = settings.COURSE_MESSAGE_SENDING_SCHEDULE_TIME.split(":")
schedule_time = localtime().replace(
hour=int(time_part[0]),
minute=int(time_part[1]),
second=int(time_part[2]),
microsecond=0,
)
for info in enrollmentinfo:
# next day after course end
if info.days_to_study_end == -1:
if info.in_scoring:
message_type = MessageService.STUDY_END_IN_SCORING
else:
message_type = MessageService.STUDY_END_FINAL
# course end
elif info.days_to_study_end == 0:
message_type = MessageService.STUDY_END_TODAY
# course start
elif info.days_from_study_start == 1:
message_type = MessageService.STUDY_START
# every week
elif info.ordinal_in_week == 1:
message_type = MessageService.STUDY_PROGRESS
else:
# exam reattempt
if info.can_reattempt:
message_type = MessageService.EXAM_REATTEMPT
else:
message_type = MessageService.STUDY_PROGRESS
messages.append(
MessageService(
receiver_id=info.user_id,
message_type=message_type,
data=MessageService.build_course_notification_data(info, message_type),
course_id=info.course_id,
schedule=schedule_time,
)
)
if messages:
MessageService.objects.bulk_create(messages, ignore_conflicts=True)
# schedule
course_message_send_task.apply_async(
eta=schedule_time,
)