2012-02-12 36 views
31

Tôi đang cố gắng sử dụng các phương thức của lớp như nhiệm vụ cần thiết của django, đánh dấu nó bằng cách sử dụng trang trí @task. Tình huống tương tự được ghi rõ here, được hỏi bởi Anand Jeyahar. Đó là một cái gì đó như thế nàysử dụng các phương pháp lớp học làm nhiệm vụ cần tây

class A: 
    @task 
    def foo(self, bar): 
     ... 

def main(): 
    a = A() 
    ... 
    # what i need 
    a.foo.delay(bar) # executes as celery task 
    a.foo(bar) # executes locally 

Vấn đề là ngay cả khi tôi sử dụng ví dụ lớp như a.foo.delay(bar) này nó nói, rằng foo nhu cầu ít nhất hai đối số, mà meens rằng self bỏ lỡ con trỏ.

Thông tin thêm:

  • tôi không thể chuyển đổi lớp để mô-đun vì thừa kế
  • Phương pháp được phụ thuộc rất nhiều vào các thành viên lớp, vì vậy tôi không thể làm cho họ tĩnh
  • Đánh dấu lớp là tác vụ với @task decorator làm cho lớp đó trở thành một nhiệm vụ và có thể thực hiện các phương thức từ phương thức run(), sử dụng một số đối số làm khóa để lựa chọn phương pháp, nhưng nó không chính xác những gì tôi muốn.
  • Tạo một thể hiện của lớp và đi qua nó như self tranh luận với các phương pháp thay đổi cách tôi thực hiện phương pháp không như taks cần tây, nhưng như phương pháp thông thường (ví dụ: trong khi thử nghiệm)
  • Tôi đã cố gắng để tìm hiểu cách thức tôi có thể đăng ký nhiệm vụ theo thực tế, từ nhà xây dựng chẳng hạn, nhưng cần tây chia sẻ mã giữa những người lao động, vì vậy đó là lý do tại sao nó dường như là không thể.

Cảm ơn sự giúp đỡ của bạn!

+0

làm cách nào để bạn thực hiện? các ví dụ tương tự cũng phù hợp với tôi. – asksol

+0

'a = A()' 'a.method (1,2)' hoặc 'a.method.delay (1,2)' - kết quả là giống nhau – eviltnan

Trả lời

40

Cần tây có hỗ trợ thử nghiệm để sử dụng các phương pháp làm nhiệm vụ kể từ phiên bản 3.0.

Các tài liệu cho điều này là trong celery.contrib.methods, và cũng đề cập đến một số hãy cẩn thận bạn nên biết:

http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html

Hãy nhận biết: hỗ trợ cho contrib.methods khỏi Cần tây từ 4,0

+0

Tôi đã thử chi nhánh của bạn. xem cập nhật. và cảm ơn) – eviltnan

+0

Thật tuyệt vời khi thấy điều này trong một phiên bản tương lai! – ThiefMaster

+1

@ThiefMaster Điều này đã có trong Celery 3.0 thực sự, xem 'celery.contrib.methods': http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html – asksol

6

Khi bạn có:

a = A() 

bạn có thể làm:

A.foo.delay(a, param0, .., paramN) 

Cheers

1

Đối với tôi là người duy nhất mà làm việc là celery.current_app vì chỉ này đi self đến phương pháp này.

Vì vậy, đây sẽ giống như thế này:

from celery import current_app 
from celery.contrib.methods import task_method 

class A: 
@current_app.task(filter=task_method, name='A.foo') 
def foo(self, bar): 
    ... 

Tên phải được sử dụng nếu bạn có phương pháp có cùng tên trong các lớp khác nhau.

3

Jeremy Satterfield có hướng dẫn rõ ràng và thẳng về phía trước để viết các nhiệm vụ dựa trên lớp nếu đó là những gì bạn muốn thực hiện. Bạn có thể kiểm tra nó here.

Sự kỳ diệu về cơ bản là mở rộng celery.Task lớp trong đó có một phương pháp run(), giống như một cái gì đó như thế này:

from celery import Task 

class CustomTask(Task): 
    ignore_result = True 

    def __init__(self, arg): 
     self.arg = arg 

    def run(self): 
     do_something_with_arg(self.arg) 

và sau đó chạy các nhiệm vụ như thế này:

your_arg = 3 

custom_task = CustomTask() 
custom_task.delay(your_arg) 

Tôi không chắc chắn nếu ignore_result = True phần là cần thiết hay không BTW.

+0

Tôi đã thử điều này, nhưng nó không hoạt động, việc ném này error - AttributeError: Ví dụ FileTask không có thuộc tính 'delay' –

+0

bạn không nên ghi đè init trong nhiệm vụ classbased. @SheeshMohsin xin vui lòng loại bỏ init và trực tiếp nhận được arg trong chạy chức năng def chạy (tự, arg): do_something_with_arg (arg) –

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