2013-08-13 33 views
7

Có cách nào tốt để chia sẻ Khóa đa xử lý giữa các nhân viên gunicorn không? Tôi đang cố gắng viết một API json với Flask. Một số các cuộc gọi API sẽ tương tác với một lớp python quản lý một tiến trình đang chạy (như ffmpeg để chuyển đổi video). Khi tôi tăng số lượng nhân viên web lên hơn 1, tôi có thể đảm bảo rằng chỉ có 1 nhân viên tương tác với lớp học cùng một lúc?Chia sẻ một khóa giữa các nhân viên gunicorn

Suy nghĩ ban đầu của tôi là sử dụng multiprocessing.Lock để hàm start() có thể là nguyên tử. Tôi không nghĩ rằng tôi đã tìm ra đúng nơi để tạo ra một Khóa để một được chia sẻ trên tất cả các công nhân:

# runserver.py 
from flask import Flask 
from werkzeug.contrib.fixers import ProxyFix 
import dummy 

app = Flask(__name__) 

@app.route('/') 
def hello(): 
    dummy.start() 
    return "ffmpeg started" 

app.wsgi_app = ProxyFix(app.wsgi_app) 

if __name__ == '__main__': 
    app.run() 

Đây là hoạt động giả của tôi:

# dummy.py 
from multiprocessing import Lock 
import time 

lock = Lock() 

def start(): 
    lock.acquire() 

    # TODO do work 
    for i in range(0,10): 
     print "did work %s" % i 
     time.sleep(1) 

    lock.release() 

Khi tôi làm mới các trang một vài lần, tôi thấy đầu ra từ mỗi cuộc gọi dệt lại với nhau.

Tôi có treo cây sai ở đây không? Có một cách dễ dàng hơn để đảm bảo rằng chỉ có bản sao của lớp xử lý (ở đây chỉ là phương thức start() giả được chạy cùng một lúc? Tôi nghĩ rằng tôi có thể cần một cái gì đó như cần tây để chạy nhiệm vụ (và chỉ sử dụng 1 công nhân) nhưng điều đó có vẻ hơi quá mức cho dự án nhỏ của tôi.

Trả lời

5

Tôi đã thử một số thứ và có vẻ như nó hoạt động. Tôi đặt preload_app = True trong số gunicorn.conf của tôi và bây giờ khóa dường như được chia sẻ. Tôi vẫn đang xem xét chính xác những gì đang xảy ra ở đây nhưng bây giờ điều này là đủ tốt, YMMV.

+0

Điều này đã giúp tôi. Cảm ơn. – ATOzTOA

3

Làm theo câu trả lời của peterw, công nhân có thể chia sẻ tài nguyên khóa.

Nhưng, tốt hơn nên sử dụng khối try-finally để đảm bảo khóa sẽ luôn được giải phóng.

# dummy.py 
from multiprocessing import Lock 
import time 

lock = Lock() 

def start(): 
    lock.acquire() 

    try: 
     # TODO do work 
     for i in range(0,10): 
      print "did work %s" % i 
      time.sleep(1) 
    finally: 
     lock.release() 
Các vấn đề liên quan