2012-10-24 14 views
10

का उपयोग करके बैंडविड्थ थ्रॉटलिंग मैं फ़ाइलों को डाउनलोड/अपलोड करने पर गति सीमा निर्धारित करने की कोशिश कर रहा हूं और पाया कि मुड़ता इस काम को संभालने के लिए twisted.protocols.policies.ThrottlingFactory प्रदान करता है, लेकिन मैं इसे सही नहीं समझ सकता। मैंने readLimit और writeLimit सेट किया है, लेकिन फ़ाइल अभी भी अधिकतम गति पर डाउनलोड हो रही है। मैं क्या गलत कर रहा हूं?ट्विस्ट

from twisted.protocols.basic import FileSender 
from twisted.protocols.policies import ThrottlingFactory 
from twisted.web import server, resource 
from twisted.internet import reactor 
import os 

class DownloadPage(resource.Resource): 
    isLeaf = True 

    def __init__(self, producer): 
     self.producer = producer 

    def render(self, request): 
     size = os.stat(somefile).st_size 
     request.setHeader('Content-Type', 'application/octet-stream') 
     request.setHeader('Content-Length', size) 
     request.setHeader('Content-Disposition', 'attachment; filename="' + somefile + '"') 
     request.setHeader('Accept-Ranges', 'bytes') 

     fp = open(somefile, 'rb') 
     d = self.producer.beginFileTransfer(fp, request) 

     def err(error): 
      print "error %s", error 

     def cbFinished(ignored): 
      fp.close() 
      request.finish() 
     d.addErrback(err).addCallback(cbFinished) 

     return server.NOT_DONE_YET 


producer = FileSender() 
root_resource = resource.Resource() 
root_resource.putChild('download', DownloadPage(producer)) 
site = server.Site(root_resource) 
tsite = ThrottlingFactory(site, readLimit=10000, writeLimit=10000) 
tsite.protocol.producer = producer 
reactor.listenTCP(8080, tsite) 
reactor.run() 

अद्यतन

तो कुछ समय बाद मैं इसे चलाने

:

2012-10-25 09:17:03+0600 [-] Unhandled Error 
Traceback (most recent call last): 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/application/app.py", line 402, in startReactor 
     self.config, oldstdout, oldstderr, self.profiler, reactor) 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/application/app.py", line 323, in runReactorWithLogging 
     reactor.run() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1169, in run 
     self.mainLoop() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/internet/base.py", line 1178, in mainLoop 
     self.runUntilCurrent() 
    --- <exception caught here> --- 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/internet/base.py", line 800, in runUntilCurrent 
     call.func(*call.args, **call.kw) 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 334, in unthrottleWrites 
     p.unthrottleWrites() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 225, in unthrottleWrites 
     self.producer.resumeProducing() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 919, in resumeProducing 
     self.consumer.unregisterProducer() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/web/http.py", line 811, in unregisterProducer 
     self.transport.unregisterProducer() 
     File "/home/chambylov/environments/transfer/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 209, in unregisterProducer 
     del self.producer 
    exceptions.AttributeError: ThrottlingProtocol instance has no attribute 'producer' 

मुझे लगता है कि मैं निर्माता आवंटित करने के लिए है कि मैं tsite.protocol.producer = producer पता है चाहिए नहीं कर रहा हूँ, मैं करने के लिए नया हूँ मुड़ गया और मुझे नहीं पता कि यह कैसे एक और तरीका है।

+1

स्रोत को देखते हुए एक रेखा है, 'लो g.msg ("थ्रॉटलिंग% s"% स्वयं पर पढ़ता है) 'क्या आप सत्यापित कर सकते हैं कि यह लॉग किया जा रहा है? – John

+0

यह * थ्रॉटल रीड्स विधियों को लॉग नहीं करता है, लेकिन यह * थ्रॉटल करता है लेखक: 'थ्रॉटलिंग ' –

+0

पर मुझे लगता है कि आपको थ्रॉटलिंग ऑब्जेक्ट को' फ़ाइल 'पढ़ने के बीच या तो सम्मिलित करना होगा और और 'रिएक्टर()', या शायद 'रिएक्टर' और आपके 'रेंडर/डाउनलोडपेज इंस्टेंस' के बीच बेहतर है। अभी आप डाउनलोडपेज और थ्रॉटलिंग ऑब्जेक्ट्स दोनों के लिए 'निर्माता' पास कर रहे हैं, यह सही नहीं लगता है। –

उत्तर

1

Every producer needs (eventually) to be registered with whatever you want to consume the data। मुझे यहां कहीं भी पंजीकरण नहीं दिख रहा है। शायद यही वह मुद्दा है जो आप कर रहे हैं?

ट्विस्टर का इस्तेमाल फ्रेंडस्टर जैसी कुछ बड़ी-कभी परियोजनाओं पर किया गया है, लेकिन सभी कॉलबैक सामान्य रूप से पायथन में लिखने के सामान्य तरीके से नहीं बैठते हैं (और मेरे पास कार्यात्मक प्रोग्रामिंग के साथ कुछ अनुभव है)। मैं gevent पर स्विच किया।

यदि आप गीवेंट पुस्तकालयों के साथ काम कर रहे हैं, तो कई विवरण (कॉलबैक/जनरेटर जो एसिंक्रोनस कार्यक्षमता प्रदान करते हैं) को समेकित किया जाता है, ताकि आप आम तौर पर अपने कोड को पैच करने और सामान्य ऑब्जेक्ट में लिखने के लिए बंद हो जाएं - केंद्रित शैली का उपयोग आप कर रहे हैं। यदि आप किसी परियोजना पर काम कर रहे हैं, जो कॉलबैक-भारी भाषा जैसे जेएस/लिस्प से अपरिचित है, तो मुझे लगता है कि वे मुड़ने पर भूगर्भ की सराहना करेंगे।

+0

यह उत्तर निर्बाध स्निपिंग के बिना बेहतर होगा (अपवर्तनीय के योग्य)। आप यह भी उल्लेख नहीं करते कि भूगर्भ प्रवाह प्रवाह के साथ कैसे व्यवहार करता है। – Glyph

+0

@Glyph वास्तव में इसके बारे में खेद है - उम्मीद है कि मैंने snarkiness हटा दिया है। ट्विस्टेड विकसित करने वाले (शानदार) लोगों के सम्मान के टोन - मेरा मतलब कोई अपराध नहीं था। शायद मेरे बुरे अनुभव से कुछ अवशिष्ट निशान। :) – egbutter

+0

इसे बदलने के लिए धन्यवाद - लेकिन आप अभी भी यह नहीं समझते कि कैसे gevent वास्तव में प्रवाह नियंत्रण के विशिष्ट मुद्दे से संबंधित है :)। – Glyph

1

egbutter ने कहा, आपको एक निर्माता को पंजीकृत करना होगा। तो यह करने के बजाय:

tsite.protocol.producer = producer 

आप एक registerProducer विधि स्पष्ट रूप से कॉल करनी होगी:

tsite.protocol.registerProducer(...) 

या, यदि आप एक निर्माता के रूप में FileSender उपयोग कर रहे हैं, अपने beginFileTransfer विधि कॉल , हमारे मामले में:

file_to_send = open(...) 
producer.beginFileTransfer(file_to_send, tsite.protocol) 
संबंधित मुद्दे