2013-08-24 45 views
21

Một số chức năng sẽ chạy không đồng bộ trên máy chủ web. Gửi email là ví dụ điển hình.Đa luồng cho Python Django

Cách tốt nhất (hoặc đa số nhất) viết một hàm trang trí để chạy hàm không đồng bộ?

thiết lập của tôi là một chung một: Python 2.4.7, Django 1.4, Gunicorn 0.17.2

Ví dụ, đây là một khởi đầu:

from threading import Thread 

def postpone(function): 
    def decorator(*args, **kwargs): 
     t = Thread(target = function, args=args, kwargs=kwargs) 
     t.daemon = True 
     t.start() 
    return decorator 

mong muốn sử dụng:

@postpone 
def foo(): 
    pass #do stuff 
+0

Nhìn vào bài này quá http://stackoverflow.com/questions/573618/django -set-up-a-schedule-job. Đối với một Job đã lên lịch chọn giải pháp dựa trên cron. Công việc theo lịch trình, nhiệm vụ không đồng bộ chọn Celery. Tôi bắt đầu bằng https://github.com/tivix/django-cron trước khi chuyển sang Celery gần đây. –

+5

Cảm ơn tất cả các câu trả lời cho đến nay, tuy nhiên Celery yêu cầu khá nhiều chi phí (cài đặt ứng dụng, tạo một db cho nó). Vì vậy, trong khi Celery là một _solution_, nó không _answer_ câu hỏi của tôi về viết một trang trí độc lập để đa luồng một chức năng. – tomcounsell

Trả lời

35

Tôi đã đăng câu hỏi trên 18 tháng trước. Kể từ đó, tôi đã tiếp tục sử dụng triển khai này ở quy mô lớn và trong sản xuất mà không có vấn đề gì.

Decorator định nghĩa:

from threading import Thread 
def postpone(function): 
    def decorator(*args, **kwargs): 
    t = Thread(target = function, args=args, kwargs=kwargs) 
    t.daemon = True 
    t.start() 
    return decorator 

Ví dụ sử dụng:

@postpone 
def foo(): 
    #do stuff 

Theo thời gian, chồng đã được cập nhật và chuyển mà không thất bại.

Nguyên bản là 2.4.7, Django 1.4, Gunicorn 0.17.2, bây giờ là Python 2.4.7, Django 1.9, Waitress 0.8.9.

Nếu bạn đang sử dụng bất kỳ giao dịch cơ sở dữ liệu, Django sẽ tạo ra một kết nối mới và điều này cần phải được tự đóng:

from django.db import connection 

@postpone 
def foo(): 
    #do stuff 
    connection.close() 
+1

Tôi cũng đang chạy việc triển khai tương tự này trong sản xuất mà không có vấn đề gì và phần tốt nhất là nó hoạt động với uwsgi mà không có bất kỳ vấn đề hiệu suất lớn nào – Deepak

+0

Bạn có giới hạn số lượng luồng được sinh ra không? Có thể ai đó gửi bom cho mã của bạn không? – CadentOrange

+0

Tôi đã không sử dụng điều này trong các tình huống mà nhiều hơn chỉ là một vài chủ đề có thể được tạo ra trong một yêu cầu web duy nhất. Tôi không có lý do để ném một chức năng sử dụng trang trí này bên trong một vòng lặp. Sẽ tốt hơn nếu chỉ đơn giản quấn logic đó vào một hàm duy nhất chạy trong một chuỗi bổ sung. Mục tiêu ở đây là trì hoãn bất kỳ quá trình xử lý nào không quan trọng để trả lại yêu cầu web. – tomcounsell

3

Cách phổ biến nhất để xử lý không đồng bộ ở Django là sử dụng Celerydjango-celery.

13

Celery là hàng đợi công việc không đồng bộ/hàng đợi công việc. Nó được tài liệu hóa và hoàn hảo cho những gì bạn cần. Tôi khuyên bạn nên bắt đầu here