<html><body>On 02:32 pm, markus@bluegap.ch wrote:<br /><br />&gt;Requests per second: &#160; &#160;494.40 [#/sec] (mean)<br /><br />&gt;Now, measured while the server is under very small load:<br /><br />&gt;Requests per second: &#160; &#160;24.37 [#/sec] (mean)<br /><br />&gt;When putting the server under real load, those response times climb up to <br /><br />What is 'real load'? &#160;Are you talking about things in process with, but not related to, the web server?<br /><br />&gt;two seconds, so there must be something wrong.<br /><br />Maybe your server is slow? :)<br /><br />&gt;Can I somehow get the reactor's state, i.e. how many deferreds are waiting <br />&gt;in the queue, how many threads are running concurrently, etc?<br /><br />There is no queue of Deferreds. &#160;They don't actually have anything to do with the reactor.<br /><br />&gt;How good is the idea of deferring File I/O to threads, i.e. <br />&gt;threads.deferToThread(self.filehandle.write, data)?<br /><br />If you do indeed discover that you are waiting a long time to write your particular stuff to files, then that might help. &#160;It might also randomly interleave the data and corrupt your files, if 'data' is big enough.<br /><br />&gt; Another possibly <br />&gt;blocking module might be the database api, but I'm using twisted's <br />&gt;enterprise adbapi, which should be async, AFAICT.<br /><br />It does the operations in threads, yes. &#160;However, the threadpool will eventually fill up; the concurrency is fairly limited. &#160;(The default is 10 or so workers, I think).<br /><br />&gt;Maybe copying data around takes time. I'm sending around chunks of 64k size <br />&gt;(streaming from the database to an external programm). Reducing chunk size <br />&gt;to 1k helps somewhat (i.e. response time is seldom over 150ms, but can still <br />&gt;climb up to &gt; 0.5 seconds).<br /><br />That's a possibility that the "--profile" option to twistd which JP suggested might help you with. &#160;You'll see the functions copying data taking a lot of CPU time in that case.<br /><br />&gt;Hum... external program.... maybe it's the self.transport.write() call which <br />&gt;blocks several 100ms? Is it safe to write:<br />&gt;<br />&gt; &#160; d = threads.deferToThread(self.transport.write, dataChunk)<br />&gt;<br />&gt;(i.e. call transport.write from a thread?)<br /><br />No. &#160;_All_ Twisted APIs are not thread safe. &#160;This call does not block though, and it is extremely, vanishingly unlikely that it is causing your problems. &#160;It just sticks some data into the outgoing queue and returns immediately.<br /><br />&gt;How much resources do these deferToThread() deferreds eat? AFAICT, the <br />&gt;reactor prepares a thread pool, which leads me to think that it's a well <br />&gt;optimized implementation...<br /><br />It's not particularly "optimized", in the sense that we haven't measured the performance or improved it much, but it's also not doing very much; put a value into a queue, get it out in a thread, do it: that's about all. &#160;It would certainly surprise me if that operation were taking 100ms.<br /><br />One quick measurement you can do to determine what might be causing this performance loss is to examine the server in 'top' while it is allegedly under load. &#160;Is it taking up 100% CPU? &#160;If not, then it's probably blocked on some kind of I/O in your application, or perhaps writing the log. &#160;If so, then there's some inefficient application code (or Twisted code) that you need to profile and optimize. &#160;The output of "strace -T" on your Twisted server *might* be useful if you discover that you're blocking on some kind of I/O.<br /></body></html>