2012-01-17 31 views
8

Tôi có một quy trình chạy dài phải chạy sau mỗi năm phút, nhưng nhiều hơn một thể hiện của các quy trình sẽ không bao giờ chạy cùng một lúc. Quá trình này thường không chạy quá năm phút, nhưng tôi muốn chắc chắn rằng một cá thể thứ hai không khởi động nếu nó chạy qua.Django Celery: Chỉ thực hiện một trường hợp của một quy trình chạy dài

Mỗi số previous recommendation, tôi đang sử dụng Django Celery để lên lịch cho tác vụ dài hạn này.

Tôi không nghĩ rằng một tác vụ định kỳ sẽ hoạt động, bởi vì nếu tôi có thời gian năm phút, tôi không muốn thực hiện nhiệm vụ thứ hai nếu một phiên bản khác của tác vụ đang chạy.

Thử nghiệm hiện tại của tôi như sau: tại 8:55, một ví dụ của tác vụ bắt đầu chạy. Khi nhiệm vụ kết thúc, nó sẽ kích hoạt một thể hiện khác của chính nó để chạy ở mốc năm phút tiếp theo. Vì vậy, nếu nhiệm vụ đầu tiên kết thúc lúc 8:57, nhiệm vụ thứ hai sẽ chạy lúc 9:00. Nếu nhiệm vụ đầu tiên xảy ra để chạy lâu và kết thúc lúc 9:01, nó sẽ lên lịch cho phiên bản tiếp theo để chạy lúc 9:05.

Tôi đã đấu tranh với một loạt các lỗi khó hiểu khi làm bất cứ điều gì nhiều hơn ví dụ đơn giản dưới đây và tôi đã không tìm thấy bất kỳ ví dụ nào khác về công việc lập lịch biểu của mọi người từ bản thân trước đó. Tôi tự hỏi liệu có cách nào tốt hơn để làm những gì tôi đang cố gắng làm không. Tôi biết có một cách để đặt tên cho nhiệm vụ của một người; có lẽ có một cách để tìm kiếm các trường hợp đang chạy hoặc được lên lịch có cùng tên? Có ai có lời khuyên nào về việc chạy một nhiệm vụ mỗi năm phút, nhưng đảm bảo rằng chỉ có một nhiệm vụ chạy cùng một lúc?

Cảm ơn bạn, Joe

Trong mymodule/tasks.py:

import datetime 
from celery.decorators import task 

@task 
def test(run_periodically, frequency): 

    run_long_process() 
    now = datetime.datetime.now() 
    # Run this task every x minutes, where x is an integer specified by frequency 
    eta = (
     now - datetime.timedelta(
     minutes = now.minute % frequency , seconds = now.second, 
     microseconds = now.microsecond)) + datetime.timedelta(minutes=frequency) 
    task = test.apply_async(args=[run_periodically, frequency,], eta=eta) 

Từ một vỏ ./manage.py:

from mymodule import tasks 
result = tasks.test.apply_async(args=[True, 5]) 

Trả lời

7

Bạn có thể sử dụng các tác vụ định kỳ được ghép nối với một khóa đặc biệt đảm bảo các tác vụ được thực hiện cùng một lúc. Đây là một thực hiện mẫu từ tài liệu cần tây:

http://ask.github.com/celery/cookbook/tasks.html#ensuring-a-task-is-only-executed-one-at-a-time

phương pháp mô tả của bạn với nhiệm vụ lập kế hoạch từ việc thực hiện trước đó có thể ngăn chặn việc thực hiện các nhiệm vụ nếu có sẽ thất bại trong một trong số họ.

+0

Cảm ơn 0x00mh. Đó là một liên kết gọn gàng. Tôi đang thử. –

Các vấn đề liên quan