2011-12-11 12 views
8

मैं asyc ग्राहक Brukva के साथ मेरी तूफान आवेदन के साथ Redis उपयोग कर रहा हूँ, जब मैं Brukva स्थल पर नमूना क्षुधा को देखा वे WebSocket में पर "init" विधि नए कनेक्शन बना रहे हैंटोरनाडो में रेडिस कनेक्शन को संभालने का सही तरीका क्या है? (Async - पब/उप)

class MessagesCatcher(tornado.websocket.WebSocketHandler): 
    def __init__(self, *args, **kwargs): 
     super(MessagesCatcher, self).__init__(*args, **kwargs) 
     self.client = brukva.Client() 
     self.client.connect() 
     self.client.subscribe('test_channel') 

    def open(self): 
     self.client.listen(self.on_message) 

    def on_message(self, result): 
     self.write_message(str(result.body)) 

    def close(self): 
     self.client.unsubscribe('test_channel') 
     self.client.disconnect() 

वेबसाइकिल के मामले में यह ठीक है लेकिन इसे सामान्य टॉरनाडो अनुरोध में कैसे संभालना हैडलर पोस्ट विधि का कहना है कि लंबे मतदान ऑपरेशन (प्रकाशित-सदस्यता मॉडल)। मैं अद्यतन हैंडलर की प्रत्येक पोस्ट विधि में नया ग्राहक connetion बना रहा हूँ यह सही दृष्टिकोण है ?? जब मैंने रेडिस कंसोल पर चेक किया तो मुझे लगता है कि ग्राहक हर नए पोस्ट ऑपरेशन में बढ़ रहे हैं।

enter image description here

यहाँ मेरी कोड का एक नमूना है।

c = brukva.Client(host = '127.0.0.1') 
c.connect() 

class MessageNewHandler(BaseHandler): 
    @tornado.web.authenticated 
    def post(self): 

     self.listing_id = self.get_argument("listing_id") 
     message = { 
      "id": str(uuid.uuid4()), 
      "from": str(self.get_secure_cookie("username")), 
      "body": str(self.get_argument("body")), 
     } 
     message["html"] = self.render_string("message.html", message=message) 

     if self.get_argument("next", None): 
      self.redirect(self.get_argument("next")) 
     else: 
      c.publish(self.listing_id, message) 
      logging.info("Writing message : " + json.dumps(message)) 
      self.write(json.dumps(message)) 

    class MessageUpdatesHandler(BaseHandler): 
     @tornado.web.authenticated 
     @tornado.web.asynchronous 
     def post(self): 
      self.listing_id = self.get_argument("listing_id", None) 
      self.client = brukva.Client() 
      self.client.connect() 
      self.client.subscribe(self.listing_id) 
      self.client.listen(self.on_new_messages) 

     def on_new_messages(self, messages): 
      # Closed client connection 
      if self.request.connection.stream.closed(): 
       return 
      logging.info("Getting update : " + json.dumps(messages.body)) 
      self.finish(json.dumps(messages.body)) 
      self.client.unsubscribe(self.listing_id) 


     def on_connection_close(self): 
      # unsubscribe user from channel 
      self.client.unsubscribe(self.listing_id) 
      self.client.disconnect() 

मैं अगर तुम इसी तरह के मामले के लिए कुछ नमूना कोड प्रदान करते हैं की सराहना करते हैं।

+0

रेडिस, जेडएमक्यू, टॉरनाडो का उपयोग करते हुए पायथन में असिंक्रोनस पबसब - https://github.com/abhinavsingh/async_pubsub –

उत्तर

2

आपको अपने ऐप में कनेक्शन को पूल करना चाहिए। चूंकि ऐसा लगता है कि ब्रुकवा स्वचालित रूप से इसका समर्थन नहीं करता है (रेडिस-पीई इसका समर्थन करता है, लेकिन प्रकृति से अवरुद्ध है इसलिए यह टर्ननाडो के साथ अच्छी तरह से नहीं चल रहा है), आपको अपना कनेक्शन पूल लिखना होगा।

पैटर्न बहुत सरल है, हालांकि। इन पंक्तियों के साथ कुछ (यह वास्तविक परिचालन कोड नहीं है):

class BrukvaPool(): 

    __conns = {} 


    def get(host, port,db): 
     ''' Get a client for host, port, db ''' 

     key = "%s:%s:%s" % (host, port, db) 

     conns = self.__conns.get(key, []) 
     if conns: 
      ret = conns.pop() 
      return ret 
     else: 
      ## Init brukva client here and connect it 

    def release(client): 
     ''' release a client at the end of a request ''' 
     key = "%s:%s:%s" % (client.connection.host, client.connection.port, client.connection.db) 
     self.__conns.setdefault(key, []).append(client) 

उसे कुछ अतिरिक्त मुश्किल हो सकता है, लेकिन यह मुख्य विचार है।

9

थोड़ा देर हो चुकी है, लेकिन मैं tornado-redis का उपयोग कर रहा हूं। यह बवंडर के ioloop साथ काम करता है और tornado.gen मॉड्यूल

स्थापित tornadoredis

यह

pip install tornadoredis 

रंज से या setuptools

easy_install tornadoredis 

साथ स्थापित किया जा सकता है, लेकिन क्या तुम सच में नहीं करना चाहिए वो करें। आप भंडार को क्लोन भी कर सकते हैं और इसे निकाल सकते हैं। तब

python setup.py build 
python setup.py install 

कनेक्ट Redis को

निम्नलिखित कोड अपने main.py में चला जाता है या समकक्ष

redis_conn = tornadoredis.Client('hostname', 'port') 
redis_conn.connect() 

redis.connect केवल एक बार कहा जाता है चलाते हैं। यह एक अवरुद्ध कॉल है, इसलिए इसे मुख्य ioloop शुरू करने से पहले बुलाया जाना चाहिए। सभी हैंडलर के बीच एक ही कनेक्शन ऑब्जेक्ट साझा किया जाता है।

आप की तरह

settings = { 
    redis = redis_conn 
} 
app = tornado.web.Application([('/.*', Handler),], 
           **settings) 

उपयोग अपने आवेदन सेटिंग पर जोड़ सकते हैं tornadoredis

कनेक्शन self.settings['redis'] पर संचालकों में इस्तेमाल किया जा सकता है या यह BaseHandler और उपवर्ग के एक संपत्ति के रूप में जोड़ा जा सकता है अन्य अनुरोध हैंडलर के लिए वह कक्षा।

class BaseHandler(tornado.web.RequestHandler): 

    @property 
    def redis(): 
     return self.settings['redis'] 

redis के साथ संवाद करने के लिए, tornado.web.asynchronous और tornado.gen.engine सज्जाकार उपयोग किया जाता है

class SomeHandler(BaseHandler): 

    @tornado.web.asynchronous 
    @tornado.gen.engine 
    def get(self): 
     foo = yield gen.Task(self.redis.get, 'foo') 
     self.render('sometemplate.html', {'foo': foo} 

अतिरिक्त जानकारी

अधिक उदाहरण और कनेक्शन पूलिंग और पाइपलाइनों जैसी अन्य विशेषताओं में पाया जा सकता जिथब रेपो

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

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