2013-02-27 19 views
8

Python RQ का उपयोग करके, हम कार्यकर्ता प्रक्रियाओं को गतिशील रूप से प्रबंधित करने की कोशिश कर रहे हैं।पाइथन आरक्यू कार्यकर्ताओं को गतिशील रूप से कैसे बंद कर दिया जाए?

from rq import Connection, Worker 

queues_to_listen_on = get_queues_to_listen_on() 

with Connection(connection = get_worker_connection()): 
    w = Worker(queues_to_listen_on) 
    w.work() 

हम विशेष रूप से श्रमिकों के बंद में रुचि रखते हैं: हम एक कस्टम निर्मित कार्यकर्ता स्क्रिप्ट है, जो (सरलीकृत रूप में) इस प्रकार है का उपयोग करें। हमारे पास मुख्य चिंता यह है कि एक कार्यकर्ता का एक सुंदर शट डाउन कैसे करें, इस तरह से बंद करने से पहले वर्तमान कार्य को समाप्त करने में सक्षम बनाया जाएगा। request_stop(...) उपयुक्त Worker ऑब्जेक्ट पर सिग्नल हैंडलर हमें जो चाहिए, वह ऐसा लगता है, लेकिन टर्मिनल में चल रहे कार्यकर्ता प्रक्रिया पर CTRL+C दबाकर इसे छोड़ने के लिए कोई रास्ता नहीं है (कम से कम मेरे ज्ञान के लिए)।

  1. प्रोग्राम rq लाइब्रेरी का उपयोग कर, request_stop को संकेत भेजने के लिए और इस तरह सुंदर शटडाउन को गति प्रदान: वरीयता के क्रम में -

    मैं इसे देख, वहाँ दो संभावित समाधान (वहाँ निश्चित रूप से अधिक हो सकता है) कर रहे हैं ।

  2. किसी भी तरह से सही प्रक्रिया के पिड को प्राप्त करें (सुनिश्चित नहीं है कि वर्कहोर प्रक्रिया या कार्यकर्ता श्रोता प्रक्रिया) और किसी अन्य विधि का उपयोग करके, उस प्रक्रिया के लिए उपयुक्त सिग्नल भेजें। हमारे पास कुछ तरीकों से किया जा सकता है, लेकिन इसे शायद अधिक काम की आवश्यकता होगी और उस समस्या के लिए अन्य चर लागू करें जिन्हें मैं छोड़ना पसंद करूंगा (उदाहरण के लिए, रिमोट कमांड या उन पंक्तियों के साथ कुछ चलाने के लिए Fabric का उपयोग करना)।

यदि इस समस्या को हल करने का एक बेहतर तरीका है या एक ही विकल्प प्राप्त करने वाला एक अलग विकल्प है, तो मैं आपके सुझावों की सराहना करता हूं।

+0

यदि आपको पीआईडी ​​की आवश्यकता है, तो आप वास्तव में इसे w.pid से प्राप्त कर सकते हैं – Borys

उत्तर

4

विकल्प 1 डिज़ाइन के मामले में निश्चित रूप से बेहतर है।

हालांकि CTRL + C उपयोग करने के लिए प्रक्रिया (मुझे लगता है कि बहुत से नफरत है) बाहर निकलने के लिए होने के अपने विशेष मुद्दे को हल करने के लिए, आप अपने कर्मचारियों के लिए निम्नलिखित रणनीति का उपयोग कर सकते हैं:

# WORKER_NAME.py 
import os 

PID = os.getpid() 

@atexit.register 
def clean_shut(): 
    print "Clean shut performed" 

    try: 
     os.unlink("WORKER_NAME.%d" % PID) 
    except: 
     pass 

# Worker main 
def main(): 
    f = open("WORKER_NAME.%d" % PID, "w") 
    f.write("Delete this to end WORKER_NAME gracefully") 
    f.close() 

    while os.path.exists("WORKER_NAME.%d" % PID): 
     # Worker working 

और अपने गुरु लिपि में, मिल @ बॉरीज़ के रूप में कार्यकर्ता पीआईडी ​​ने सुझाव दिया है कि शानदार बंद करने के लिए गर्म स्टॉप अनुरोध, और os.unlink("path/to/WORKER_NAME.%d" % worker_PID) भेजें :)

यह केवल अनिश्चितकालीन पाश चलाने वाले श्रमिकों पर लागू होगा। यदि कार्यकर्ता प्रक्रिया उन चीजों को बुलाती है जो सादे अनुक्रमिक एक-बार नौकरी को अवरुद्ध करते हैं, तो आपको वहां से हल करने के लिए संभावित रूप से अवरुद्ध करने के लिए आगे बढ़ना होगा, जैसे कि कुछ प्रकार की टाइम-आउट रणनीति लागू करें।

संबंधित मुद्दे