2014-09-03 21 views
10

Tôi đã từng có một chức năng như thế nàyCần tây và tín hiệu

def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result) 

    return result 

đâu result_higher_then_four rõ ràng là đại diện cho một tín hiệu.

Sau đó, tôi đã giới thiệu cần tây và chức năng của tôi trông giống như dưới đây và tôi không bao giờ nhận được tín hiệu nữa. Tôi cho rằng các tín hiệu bị ràng buộc trong một quá trình và khi cần tây chạy trong một quá trình khác, điều này có nghĩa là tôi không thể bắt tín hiệu trong quá trình chính. Tôi có nên sử dụng một số thread_local để sửa lỗi này không? Hay tôi nhìn thấy rõ ràng?

Cảm ơn

@task 
def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result) 

    return result 
+0

@ChillarAnand có – user2298943

Trả lời

2

Sự cố là bộ thu tín hiệu không được đăng ký. Các công nhân cần tây chạy trong quy trình riêng của họ để các kết nối tín hiệu cần được thực hiện trong quá trình đó. Nếu bạn biết chúng là gì hoặc có thể khám phá chúng, bạn có thể đăng ký chúng trong khi khởi tạo tác vụ bằng cách sử dụng this technique.

Tất nhiên, điều đó giúp loại bỏ một số lợi ích của việc sử dụng tín hiệu ngay từ đầu vì bạn cần phải biết trước các kết nối.

Một ý tưởng là giả định rằng bộ nhận tín hiệu sẽ luôn đăng ký trong mô-đun mô hình của từng ứng dụng. Trong trường hợp này, các thao tác sau sẽ hoạt động.

class CalculateTask(celery.Task): 

    def __init__(self): 
     from django.conf import settings 
     for app in settings.INSTALLED_APPS: 
      app_models = '{}.{}'.format(app,'models') 
      __import__(app_models, globals=globals())         

    def run(self, input): 
     result = input * 2 
     if result > 4: 
      result_higher_then_four.send(result) 

     return result 
0

Nếu tôi hiểu đúng bạn muốn quá trình tương tự để gửi ans nhận được tín hiệu nó gửi? nếu vậy tại sao không sử dụng:

os.kill(os.getpid(), signal.SIGUSER1) 

và xác định trình xử lý cho SIGUSR1 cho phù hợp?

nếu bạn muốn có một quy trình khác, bạn phải có pid để gửi tín hiệu đến nó, chỉ cần sử dụng lệnh tương tự mà tôi đã cung cấp ở đây với pid đúng thay vì os.getpid(). Trừ khi tôi bỏ lỡ điều gì đó?

2

Bạn có thể sử dụng các tín hiệu celeryd_init để khởi tạo người lao động và tín hiệu http://celery.readthedocs.org/en/latest/userguide/signals.html#celeryd-init

Dựa trên những gì mà bạn cung cấp của bạn, tôi đã thử nghiệm với:

from celery.signals import celeryd_init 
from celery.utils.dispatch import Signal 

def process_result(result, *args, **kwargs): 
    print "signals received: %s" % result 

result_higher_then_four = Signal() 

@celeryd_init.connect 
def init_signals(*args, **kwargs): 
    result_higher_then_four.connect(process_result) 

@task(bind=True) 
def calculate(self, input): 
    result = input * 2 

    if result > 4: 
     result_higher_then_four.send(result=result, sender=self) 

    return result 
+0

này là đúng . Tôi nghĩ OP cũng có thể sử dụng chuỗi để đạt được điều tương tự nhưng dễ đọc. Xem ví dụ tại đây http://docs.celeryproject.org/en/latest/userguide/tasks.html#avoid-launching-synchronous-subtasks – chhantyal

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