मैं ऐसे एप्लिकेशन पर काम कर रहा हूं जो क्लाइंट-सर्वर कनेक्शन का समर्थन करे। ऐसा करने के लिए, मैं टर्ननाडो के मॉड्यूल का उपयोग कर रहा हूं जो मुझे वेबसाकेट बनाने की अनुमति देता है। मैं कम से कम सर्वर-साइड ऑपरेशन में हमेशा रहने का इरादा रखता हूं। इसलिए मैं इन कनेक्शनों पर बनाए गए प्रत्येक ऑब्जेक्ट के प्रदर्शन और स्मृति उपयोग के बारे में बहुत चिंतित हूं। मैंने पुस्तकालय द्वारा वास्तव में इन वस्तुओं को समाप्त करने के दौरान परीक्षण करने के लिए परीक्षण करना शुरू कर दिया है। उदाहरण कोड ले लो और मैं विधि __del__()
पायथन - WebSocketHandler और TornadoWebSocketClient कब पूरी तरह हटा दिए जाते हैं?
server.py
#! /usr/bin/env python
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import gc, sys
import resource
class WSHandler(tornado.websocket.WebSocketHandler):
def open(self):
print 'new connection'
self.write_message("h")
def check_origin(self, origin):
return True
def on_message(self, message):
print "Message: " + message
def on_close(self):
print 'Closed'
print 'GC count: ' + str(len(gc.get_referrers(self)))
def __del__(self):
print "DELETED"
application = tornado.web.Application([
(r'/s', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8888)
tornado.ioloop.IOLoop.instance().start()
client.py
#! /usr/bin/env python
from ws4py.client.tornadoclient import TornadoWebSocketClient
from tornado import ioloop
class MainClient(TornadoWebSocketClient):
def opened(self):
print "Connected"
def received_message(self, message):
print "Message"
#I close the connection
self.close()
def closed(self, code, reason=None):
print "Closed"
ioloop.IOLoop.instance().stop()
def __del__(self):
print "DELETED"
if __name__ == "__main__":
ws = MainClient('ws://localhost:8888/s', protocols=['http-only', 'chat'])
ws.connect()
ioloop.IOLoop.instance().start()
जब ग्राहक एक संदेश प्राप्त अधिलेखित कर दिया है, यह कनेक्शन बंद कर देता है। मुझे उम्मीद थी कि दोनों ऑब्जेक्ट्स को हटा दिया गया था, क्योंकि कनेक्शन बंद था, और इसलिए __del__()
विधि को कॉल करें, लेकिन ऐसा नहीं हुआ।
सर्वर उत्पादन:
new connection
Closed
GC count: 6
ग्राहक उत्पादन:
Connected
Message
Closed
आप देख सकते हैं यह DELETED
वाक्य है कि मैं __del__()
विधि से उम्मीद कर रहा था मुद्रित नहीं किया।
--edited--
इसके अलावा, मैं लाइन है कि जो कनेक्शन बंद करने के समय में उस वस्तु की जीसी है सन्दर्भ की संख्या प्रिंट जोड़ दिया है। यह साबित करता है कि वास्तव में संदर्भ चक्र हैं।
-----
जाहिर वर्गों है कि मैं का उपयोग उन लोगों की तुलना में अधिक जटिल हो जाएगा होगा, लेकिन मुझे दोनों वस्तुओं के व्यवहार है, जो कि मैं क्या सच में जानना चाहते हैं है समझने में मदद: जब क्या वे हटा दिए गए हैं? जब उन्हें हटाते हैं तो यह स्मृति को मुक्त करता है? या अन्यथा किसी भी तरह से बन रहे हैं? या ¿वस्तु को स्पष्ट रूप से कैसे हटाएं?
मैंने tornado.websocket.WebSocketHandler
documentation पढ़ा, यह मुझे बताता है कि ऑब्जेक्ट "बंद" है, लेकिन मुझे नहीं पता कि स्मृति कब जारी की जाती है।
उन संदर्भ चक्र से बचने के लिए (पैच एक कनेक्शन के बाद संदर्भ चक्र को तोड़ने के लिए स्वागत किया जाएगा बंद कर दिया है), होगा 'एक विकल्प weakref'? या इसे करने के लिए कुछ भी नहीं है? –
मुझे यकीन नहीं है कि मौजूदा जीसी में चक्रों के साथ 'कमजोर' मदद करता है (कमजोर संदर्भ सहित एक चक्र अभी भी एक चक्र है)।इस मामले में हमारे पास पहले से ही कुछ स्पष्ट सफाई कोड है (जहां हम IOStream को बंद करते हैं और IOLoop से हैंडलर को हटाते हैं), इसलिए हमें यह सुनिश्चित करने की आवश्यकता है कि कोई भी विशेषता जो चक्र का कारण बन सकती है (और अब इसकी आवश्यकता नहीं है) किसी को भी सेट नहीं किया गया है । –