Джанго + фон-задачи как инициализировать - PullRequest
0 голосов
/ 16 мая 2018

У меня есть базовые проекты django, которые я использую в качестве интерфейса интерфейса для вычислительного кластера (Condor) для генерации симуляций. Из приложения django пользователи могут запускать симуляции (в Condor). Связанные с симуляцией метаданные и состояние симуляции хранятся в БД.

Мне нужно добавить новую функцию: уведомление, когда (некоторые) симуляции сделаны.

Поскольку я хочу простое решение (а я уже использую фоновые задачи), я подумал о том, чтобы использовать повторяющуюся задачу, которая через фиксированные промежутки времени запрашивает Condor о задачах, обновляет БД и при необходимости отправляет уведомления.

Так что если я хочу каждые 10 минут обновлять статусы, у меня будет что-то вроде:

@background(schedule=1)
def check_simulations(repeat=600):
    # lookup simulation statuses
    simulation_list = get_Simulations()
    for sim in simulations_list:
       if sim.status == Simulation.DONE:
            user.email_user('Simulation Complete', 'You have been notified')

def initialize():
     check_simulations()

Однако эта задача (или, точнее, метод initialize ()) должна быть запущена (вызвана один раз), чтобы создать и запланировать задачу check_simulations () (которая практически сериализует вызов и сохранит его в БД); после этого поток фоновых задач прочитает его и выполнит, а также перепланирует (если есть ошибка)

Мои вопросы:

  • куда мне поместить вызов метода initialize (), который будет запущен только один раз?

Одним из таких мест может быть, например, urls.py, но это крайне уродливое решение. Есть ли лучший способ?

  • как убедиться, что при перезапуске сервера не будет создано и запланировано новое задание (если оно уже существует) Это может произойти, если задача уже запланирована (так что сериализованная задача находится в таблице фоновых задач), и веб-сервер перезапускается, поэтому метод initialize () вызывается снова, чтобы создать и запланировать новую задачу ...

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

У меня была похожая проблема, и я решил ее таким образом.

Я инициализирую свою задачу в urls.py, я не знаю, можете ли вы использовать другие места, чтобы поставить ее, также добавили и если, чтобы проверитьесли задача уже есть в базе данных

from background_task.models import Task
if not Task.objects.filter(verbose_name="update_orders").exists():
   tasks.update_orders(repeat=300, verbose_name="update_orders")

, я проверил ее и она работает нормально, вы также можете искать заказ с другими параметрами, такими как name, hash, ...

Вы можете проверить модель задачи здесь: https://github.com/arteria/django-background-tasks/blob/master/background_task/models.py

0 голосов
/ 16 мая 2018

Из официального документа фоновая задача может быть инициализирована декоратором background, как показано ниже

from background_task import background
from django.contrib.auth.models import User

@background(schedule=60)
def notify_user(user_id):
    # lookup user by id and send them a message
    user = User.objects.get(pk=user_id)
    user.email_user('Here is a notification', 'You have been notified')


Q.1 : Где лучше всего поставить эти задачи?
Вы можете написать это где угодно как любой модуль / файл python. По моему мнению, создайте модуль task.py и поместите эти функции задачи туда. task.py имеет больше смысла, верно?

Q.2 : Как избежать дублирования задач?
Из документ ,

Когда повторяющееся задание завершается успешно, новое задание с смещение повтора планируется. С другой стороны, если повторяющееся задание не удается и не перезапускается, цепочка повторения останавливается.

Следовательно, я думаю, что нет шансов для создания дублирующих задач

...