[Twisted-Python] [patch] 1/4 process disconneting

Here a list of fixes present in CPUShare-Twisted mercurial tree and missing in Twisted SVN trunk. Most of these have been posted as a ticket in trac without feedback (by now the links in the tickets are obsolete due to bugs in tailor that required a rebuild of the SVN->HG repository, but nobody asked about the dangling link anyway). So I rensend them here just in case somebody is interested. I will not answer to replies because I've no time, sorry. Each email contains one patch. This fixes a reentrance problem in connectionLost if invoked by shutdown at the same time as the real disconnect. diff -r 493b5c24e0f3 twisted/internet/process.py --- a/twisted/internet/process.py Tue May 16 04:57:00 2006 +0000 +++ b/twisted/internet/process.py Wed May 17 15:59:28 2006 +0200 @@ -82,7 +82,24 @@ def detectLinuxBrokenPipeBehavior(): # Call at import time detectLinuxBrokenPipeBehavior() -class ProcessWriter(abstract.FileDescriptor): +class ProcessReaderWriter(abstract.FileDescriptor): + """(Internal) Helper class to avoid code duplication between + ProcessReader and ProcessWriter.""" + def connectionLost(self, reason): + """Close my end of the pipe, signal the Process (which signals the + ProcessProtocol). + See also abstract.FileDescriptor.connectionLost. + """ + # connectionLost can be called multiple times, for example + # both from the loseConnection timer, and from the + # shutdown event as well, but childConnectionLost + # needs to be invoked only once + disconnected = self.disconnected + abstract.FileDescriptor.connectionLost(self, reason) + if not disconnected: + self.proc.childConnectionLost(self.name, reason) + +class ProcessWriter(ProcessReaderWriter): """(Internal) Helper class to write into a Process's input pipe. I am a helper which describes a selectable asynchronous writer to a @@ -174,14 +191,8 @@ class ProcessWriter(abstract.FileDescrip else: self.stopReading() - def connectionLost(self, reason): - """See abstract.FileDescriptor.connectionLost. - """ - abstract.FileDescriptor.connectionLost(self, reason) - self.proc.childConnectionLost(self.name, reason) - - -class ProcessReader(abstract.FileDescriptor): + +class ProcessReader(ProcessReaderWriter): """ProcessReader I am a selectable representation of a process's output pipe, such as @@ -224,13 +235,6 @@ class ProcessReader(abstract.FileDescrip self.disconnecting = 1 self.stopReading() self.reactor.callLater(0, self.connectionLost, failure.Failure(CONNECTION_DONE)) - - def connectionLost(self, reason): - """Close my end of the pipe, signal the Process (which signals the - ProcessProtocol). - """ - abstract.FileDescriptor.connectionLost(self, reason) - self.proc.childConnectionLost(self.name, reason) class Process(styles.Ephemeral):

I noticed processEnded is called by threads. This generates a subtle race condition for most code (or at least for my code). The fact processEnded is called from threads isn't documented anywhere and so I prefer to be safe than sorry since I assume most code is written thinking processEnded will run in the usual serialized context and not in a parallel racy thread. diff -r 493b5c24e0f3 twisted/internet/posixbase.py --- a/twisted/internet/posixbase.py Tue May 16 04:57:00 2006 +0000 +++ b/twisted/internet/posixbase.py Wed May 17 15:59:28 2006 +0200 @@ -189,7 +189,7 @@ class PosixReactorBase(ReactorBase): if platformType == 'posix': signal.signal(signal.SIGCHLD, self._handleSigchld) - def _handleSigchld(self, signum, frame, _threadSupport=platform.supportsThreads()): + def _handleSigchld(self, signum, frame): """Reap all processes on SIGCHLD. This gets called on SIGCHLD. We do no processing inside a signal @@ -198,10 +198,7 @@ class PosixReactorBase(ReactorBase): eventloop round prevents us from violating the state constraints of arbitrary classes. """ - if _threadSupport: - self.callFromThread(process.reapAllProcesses) - else: - self.callLater(0, process.reapAllProcesses) + self.callLater(0, process.reapAllProcesses) def startRunning(self, installSignalHandlers=1): # Just in case we're started on a different thread than

This is an old patch, it wasn't applied because not all transport backends support disconnecting but since I assume most people uses the basic int32/16 protocols on top of tcp this isn't a pratical concern for me, and I prefer no data callback to fire after calling loseConnection. This isn't an high prio patch but I post it anyway (I understand if it will not be applied to SVN again for the valid reason that disconnecting may not exists, I admit I never investigated since I only use tcp and udp, my argument that disconnecting could be added in a compatible transparent way to all transports still holds). diff -r 493b5c24e0f3 twisted/protocols/basic.py --- a/twisted/protocols/basic.py Tue May 16 04:57:00 2006 +0000 +++ b/twisted/protocols/basic.py Wed May 17 15:59:28 2006 +0200 @@ -309,7 +309,7 @@ class Int32StringReceiver(protocol.Proto """Convert int32 prefixed strings into calls to stringReceived. """ self.recvd = self.recvd + recd - while len(self.recvd) > 3 and not self.paused: + while len(self.recvd) > 3 and not self.paused and not self.transport.disconnecting: length ,= struct.unpack("!i",self.recvd[:4]) if length > self.MAX_LENGTH: self.transport.loseConnection() @@ -346,7 +346,7 @@ class Int16StringReceiver(protocol.Proto """Convert int16 prefixed strings into calls to stringReceived. """ self.recvd = self.recvd + recd - while len(self.recvd) > 1 and not self.paused: + while len(self.recvd) > 1 and not self.paused and not self.transport.disconnecting: length = (ord(self.recvd[0]) * 256) + ord(self.recvd[1]) if len(self.recvd) < length+2: break

I started using web2 in production about 4 months ago and it's stable (there were bugs but I've fixed them all). Grepping for 'grep -ri nevow' over my tree shows zero hits for about two months. The web2 API rightfully isn't stable but people that is ok with slight change of APIs (changes that hopefully won't require a total rewrite of the application) should be allowed to start porting their apps to web2, and infact in the last 4 months the API has not changed singificantly, and it seems quite mature, much better than web1. It is now time to make web2 mainstream, implementing any potentially missing feature (I never tested the web2 client side for example, that may not be mature as the server side yet) and leave for web3 any huge changes that isn't strictly necessary and that would requires a total rewrite of the apps. Twisted-web userbase shouldn't lose more time on the obsolete twisted.web1 api. There is people like me that needs something with much more scalable and simpler to code with than web1+neovw. twisted.web2 + cheetah (or other rendering templates) fills this gap nicely. I hope that the huge nevow dependency of divmod products generates no conflict of interest with change. Web2 always gest installed in Twisted-HG (including all web2 fixes that are pending and that I'll post to twisted-web list shortly). diff -r 493b5c24e0f3 setup.py --- a/setup.py Tue May 16 04:57:00 2006 +0000 +++ b/setup.py Wed May 17 15:59:35 2006 +0200 @@ -11,7 +11,7 @@ import sys, os, glob # Projects to which `all' refers. sumoSubprojects = ['core', 'conch', 'lore', 'mail', 'names', - 'runner', 'web', 'words', 'news'] + 'runner', 'web', 'words', 'news', 'web2',] specialPaths = {'core': 'twisted/topfiles/setup.py'}

On Wed, 17 May 2006 16:51:06 +0200, Andrea Arcangeli <andrea@cpushare.com> wrote:
I started using web2 in production about 4 months ago and it's stable (there were bugs but I've fixed them all). Grepping for 'grep -ri nevow' over my tree shows zero hits for about two months. The web2 API rightfully isn't stable but people that is ok with slight change of APIs (changes that hopefully won't require a total rewrite of the application) should be allowed to start porting their apps to web2, and infact in the last 4 months the API has not changed singificantly, and it seems quite mature, much better than web1.
"allowed"? What's stopping anyone from using it?
It is now time to make web2 mainstream, implementing any potentially missing feature (I never tested the web2 client side for example, that may not be mature as the server side yet) and leave for web3 any huge changes that isn't strictly necessary and that would requires a total rewrite of the apps. Twisted-web userbase shouldn't lose more time on the obsolete twisted.web1 api. There is people like me that needs something with much more scalable and simpler to code with than web1+neovw. twisted.web2 + cheetah (or other rendering templates) fills this gap nicely. I hope that the huge nevow dependency of divmod products generates no conflict of interest with change. Web2 always gest installed in Twisted-HG (including all web2 fixes that are pending and that I'll post to twisted-web list shortly).
Sorry, you don't get to dictate the course of development of projects you don't even usefully contribute to. twisted.web2 is unstable and will continue to change incompatibly until at least the _obvious_ shortcomings have been addressed. Jean-Paul

On Wed, 17 May 2006 16:31:56 +0200, Andrea Arcangeli <andrea@cpushare.com> wrote:
I noticed processEnded is called by threads. This generates a subtle race condition for most code (or at least for my code). The fact processEnded is called from threads isn't documented anywhere and so I prefer to be safe than sorry since I assume most code is written thinking processEnded will run in the usual serialized context and not in a parallel racy thread.
No it isn't. The bug you imagine here is non-existent. There is nothing to be fixed. Jean-Paul

On Wed, 17 May 2006 16:31:56 +0200, Andrea Arcangeli <andrea@cpushare.com> wrote:
I noticed processEnded is called by threads.
As exarkun noted in the ticket, which is where Andrea should have responded in the first place: http://twistedmatrix.com/trac/ticket/1667 Andrea don't understand the purpose of that code (he's effectively reading it backwards) and disabling it will make the situation with processes and threads worse, not better. Please don't apply this patch (or any of his patches) to your own copies of Twisted. Also, please don't follow his example and re-post your own patches which have been rejected because they are buggy to the mailing list. I hope that everyone on this list has the good sense not to listen to Mr. Arcangeli's creative interpretations of reality by now, but in case not, this line should give you a clue:
(there were bugs but I've fixed them all)
This from a man who believes that unit tests are a "waste of time". It may indeed be possible to use some random snapshot of web2 in a production setting; however, you have a virtual guarantee from the entire Twisted team that the web2 API _will_ change incompatibly before it's released, and that we will _not_ support any use of it before then. I am personally hoping that we can make some major incompatible changes, (as I have said before) specifically the substitution of something else for the deferred 'streams' API. I'm not a web2 maintainer so I might be talked out of that *specific* change, but it's just an example. (Keep in mind that the only person willing to support it does not have time to write unit tests for his own code, or read responses to tickets he has filed explaining why his understanding is incorrect.) If you want to accelerate the process of web2 actually being maintained and supported as a stable API, we're always interested in hearing about donations of resources or time. Divmod, in particular, would like to have some excuse to help web2 get finished so we can port Nevow over and stop supporting web1, but we don't have any resources of our own to spare at the moment.

Andrea don't understand the purpose of that code (he's effectively reading it backwards) and disabling it will make the situation with processes and threads worse, not better. Please don't apply this patch (or any of his patches) to your own copies of Twisted.
I didn't want to answer but I think I should to confirm that for this single patch (2/4 posted to python-twisted) they're right: I misread the code because defertothread(callback) means defer the callback to the thread, but callfromthred _doesn't_ mean to call the callback from the thread. callfromthread means to call the callback from the main event loop instead, great API naming I would say. But for all other patches I posted, they should be applied to everybody's own twisted copy. Including the "no it isn't", since the bug exists and needs fixing or I get exceptions. If trac would have posted me updates via email I wouldn't have been forced to resubmit here. I got zero feedback and I've better things to do than to poll trac (I even tried to poll track but I couldn't find my tickets anymore, probably because you closed them and I got no notification by email). Perhaps I didn't include myself in some CC list or whatever, but in all bugtracking software I used in my life so far, I never needed to add myself to a CC list if I was the very submitter of the report, perhaps trac is different I don't know, apologies for that if that's the case. Overall using twisted for my project was a mistake. One major core design problem it has is that it can't pass POLLERR|POLLHUP|POLLNVAL to the poll syscall unless POLLIN/POLLOUT are set too. This means that if I throttle the I/O I can't notice anymore when a disconnect happens. But the severe core design issues it has would be fixable and they are a minor problem compared to the behaviour of some elements of the community that exists around it. I don't need to enter the details myself, if doc/fun/Twisted.Quotes isn't enough, quoting emails like these is more than enough: http://twistedmatrix.com/pipermail/twisted-python/2006-May/013137.html http://www.mail-archive.com/twisted-web%40twistedmatrix.com/msg00352.html (sadly there are many more) The only bit for which I prefer to enter into the details (just in case somebody didn't notice) is that the guy puts me words in my mouth that I never said and that I never thought either. Specifically I never said unittest are a waste of time, I only said that I don't have time to write unittests and that lack of unittests should not prevent valid bugfixes to be included and I think this is a very reasonable development approach. We can argue about features or huge changes, but I think valid bugfixes should not require unittests. If somebody sends me a huge amount of unittests I will apply them immediately. The more unittests the better! Exactly the opposite of "unittests are a waste of time" that the guy claimed that I have said. I even written "unittests are welcome" it in the CPUShare-Twisted homepage, the last change in that page happened 2006-02-16, so quite a few months ago. http://www.cpushare.com/twisted In the CPUShare-Twisted fork fixes and new features will be applied without formalities. Notably, unit-tests are welcome, but they're certainly not mandatory for inclusion of new features and bugfixes. If you've objectives to reach quickly and you don't want having to maintain your own version of Twisted, you may find this project useful to you.

On May 18, 2006, at 3:25 PM, Andrea Arcangeli wrote:
If trac would have posted me updates via email I wouldn't have been forced to resubmit here. I got zero feedback and I've better things to do than to poll trac (I even tried to poll track but I couldn't find my tickets anymore, probably because you closed them and I got no notification by email). Perhaps I didn't include myself in some CC list or whatever, but in all bugtracking software I used in my life so far, I never needed to add myself to a CC list if I was the very submitter of the report, perhaps trac is different I don't know, apologies for that if that's the case.
Yes! This is a major problem with our installation of trac. Submitters and commentators don't get any emails unless they manually add themselves to the CC list. James

On Thu, 18 May 2006 21:25:07 +0200, Andrea Arcangeli <andrea@cpushare.com> wrote:
Andrea don't understand the purpose of that code (he's effectively reading it backwards) and disabling it will make the situation with processes and threads worse, not better. Please don't apply this patch (or any of his patches) to your own copies of Twisted.
I didn't want to answer but I think I should to confirm that for this single patch (2/4 posted to python-twisted) they're right: I misread the code because defertothread(callback) means defer the callback to the thread, but callfromthred _doesn't_ mean to call the callback from the thread. callfromthread means to call the callback from the main event loop instead, great API naming I would say.
I understand that English isn't your first language, and I don't blame you for that, but you can find the documentation for these APIs here: http://twistedmatrix.com/documents/current/api/twisted.internet.interfaces.I... and I think the descriptions are easy enough to understand. The API logic is this: If you have a function and you are running in the reactor, but you want to CALL that function IN a THREAD, you use callInThread. If you are running in a thread already, and you want to CALL a function that uses Twisted APIs (such as the reactor) FROM that THREAD, you use callFromThread. Perhaps "invokeArgumentInThreadpool" or "dispatchCallableToReactorForThreadSafety" would have been better names, but I already wear out my keyboards fast enough.
But for all other patches I posted, they should be applied to everybody's own twisted copy. Including the "no it isn't", since the bug exists and needs fixing or I get exceptions.
Since you've already demonstrated that you don't bother to read the documentation, write tests, or even understand the difficulties that may or may not exist before you submit a patch and apply it to your branch, I don't doubt that tracebacks happen, but I doubt that they're the problem you have identified. The reason we require unit tests is the same reason scientists require *reproducible* experiments. If you don't submit a test that can easily produce the traceback you saw, how else would we know that some local misconfiguration on your system wasn't causing it.
If trac would have posted me updates via email ...
o/` If I only had a brain o/` da dee da dee da da dum o/` Trac isn't perfect, but despite some minor complaints everyone else is managing to use it. Like Twisted, Trac is written in Python, and if you want it to send you email, you can submit plugins and suggest that we use them. Also, you can learn how to click on a bookmark, or even update an RSS feed. Here's a single convenient page you can poll for all your tickets - including those that have been closed - and it does have an "RSS" button at the bottom so you can monitor changes: http://twistedmatrix.com/trac/query?reporter=andrea
Overall using twisted for my project was a mistake.
And yet, and yet, and yet...
One major core design problem it has is that it can't pass POLLERR|POLLHUP|POLLNVAL to the poll syscall unless POLLIN/POLLOUT are set too.
This is definitely a bug. I wouldn't term it a "major core design problem", since I think it can be affected even without changing any external APIs. Oddly enough, you submitted a bug in the tracker about it, which could have been found either with trac's search field or the above query. In fact it's also the first hit for "POLLHUP POLLNVAL twisted" on google. However, since both Trac and Google are far too much work for busy, important men like yourself, I've included a link here: http://twistedmatrix.com/trac/ticket/1662 A response has been posted within the last month, with a comment indicating that it will be fixed.
This means that if I throttle the I/O I can't notice anymore when a disconnect happens.
The last paragraph of the ticket's description begins: "Currently I don't strictly need this" I doubt that we'd necessarily do anything that was important to you in particular, but *even you* have said that this isn't really that important. It is hypocrisy of the worst order to bring it up in this discussion as a critical, severe problem that indicates the failure of the whole community.
But the severe core design issues it has would be fixable and they are a minor problem compared to the behaviour of some elements of the community that exists around it. I don't need to enter the details myself, if doc/fun/Twisted.Quotes isn't enough, quoting emails like these is more than enough:
"I know you are but what am I!?!?" You're the one who won't follow simple rules of politeness like "use the tracker" or "write unit tests if you require your patches be applied". You're the one who throws around baseless insults and lies about other peoples' code. Your factual errors about Nevow during the period when you were abandoning it were too numerous to even taxonomize -- when have I ever said anything nasty about CPUShare? Even considering these abuses, we still haven't rejected your access to our resources, including our mailing list and our bugtracker. In fact, as evidenced above, effort and thought is going into fixing issues that you've reported! And yet, because somebody once told a fart joke on an IRC channel, you *still* have the gall to say that our "behavior", as a whole community, is too difficult for anyone to deal with. Since explicit is better than implicit, why don't I just say this right out: you are a humorless, self-important, obnoxious jerk. You need to seriously consider your own behavior before you start insulting others.
Specifically I never said unittest are a waste of time
Ahem. From http://twistedmatrix.com/pipermail/twisted-web/2006-January/002389.html """
So I'm going to fork twisted into a private twisted-CPUShare branch for my own server use where I won't have to waste time to fix bugs """
At least as I understood it, "waste time" == "write unittests" in that context, since the whole point of this fork is that you didn't want to write tests to get bug-fixes applied. You are correct that you didn't ever write, word for word, "unit tests are a waste of time" but numerous other things you said implied it.

On May 18, 2006, at 2:34 PM, glyph@divmod.com wrote:
I understand that English isn't your first language, and I don't blame you for that, but you can find the documentation for these APIs here:
http://twistedmatrix.com/documents/current/api/ twisted.internet.interfaces.IReactorThreads.html
and I think the descriptions are easy enough to understand.
Actually, English is my first language, and I'm confused every time I see those functions. It's probably too late to change the name, but might I suggest changing the first sentence of callFromThread's docstring from: Call a function from within another (i.e. non-reactor) thread. to: Cause a function to be executed asynchronously on the reactor thread. This is the language used by SwingUtilities.invokeLater(), which I've always found comparatively clear. http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/ SwingUtilities.html#invokeLater(java.lang.Runnable) Regards, Scott -- Scott Lamb <http://www.slamb.org/>

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Indeed. <http://twistedmatrix.com/trac/ticket/1726>! Scott Lamb wrote:
Actually, English is my first language, and I'm confused every time I see those functions. It's probably too late to change the name, but might I suggest changing the first sentence of callFromThread's docstring from:
Call a function from within another (i.e. non-reactor) thread.
to:
Cause a function to be executed asynchronously on the reactor thread.
This is the language used by SwingUtilities.invokeLater(), which I've always found comparatively clear.
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SwingUtilities.html#invo...)
Regards, Scott -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (MingW32) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFEbQnz3A5SrXAiHQcRAnbCAKCOvvp/SDJjEoHuxCjHjPNq3aZfigCffFbA yMD3vh9kAg7Y8cLOWqrG2CI= =ngPU -----END PGP SIGNATURE-----

Scott Lamb wrote:
On May 18, 2006, at 2:34 PM, glyph@divmod.com wrote:
I understand that English isn't your first language, and I don't blame you for that, but you can find the documentation for these APIs here:
http://twistedmatrix.com/documents/current/api/ twisted.internet.interfaces.IReactorThreads.html
and I think the descriptions are easy enough to understand.
Actually, English is my first language, and I'm confused every time I see those functions...
I'm not a native speaker, but given twisteds concurrency model, how could one assume reactor.callFromThread gets executed anywhere but in the reactor? Nothing else makes sense, or put as a question, what else does? You call something f r o m a thread, using a member-function of the one and only reactor. The only way to get that wrong is to think of the thread in callFromThread as the reactor-thread. The main loop of an asynchronous app is way too special to name it just thread, thatswhy its name is reactor, so the other way round it might be callFrom/InReactor, which imo would make it by far less obvious that this is an interface to threads. Johann

On Thu, May 18, 2006 at 09:25:07PM +0200, Andrea Arcangeli wrote:
http://twistedmatrix.com/pipermail/twisted-python/2006-May/013137.html http://www.mail-archive.com/twisted-web%40twistedmatrix.com/msg00352.html
(sadly there are many more)
Within a few hours here one more that can be added to the list: http://twistedmatrix.com/pipermail/twisted-python/2006-May/013158.html The guy is kind enough not to blame me for not speaking english as my first native language, but yet he's trying to teach me english by saying that unittests are a "waste of time" ---quote--- This from a man who believes that unit tests are a "waste of time". ---quote--- means the same as "I won't have to waste time to fix bugs". In my minimal english language understananding, it was clear that with "wasted time to fix bugs" I meant "the time between fixing the bug and deploying the bugfix in production (or to the userbase)". I never said, believed, thought or meant that writing an unit test is a waste of time at large, as proven by the CPUShare-Twisted homepage that explicitly says for the last 3 months "unittest are welcome". Why should they be welcome if they are "a waste of time"? But then the fact the guy puts words in my mouth that I never said in order to make me look like an idiot is after all a minor thing compared to the rest he says. But let's ingore the usual politcally correct behaviour I receive from some element of this community and let's stick to technical facts: 1) callFromThread should be renamed callFromReactor (no need to make up long names when it actually means callFromReactor) 2) verifying a bugfix correctness doesn't require unittests in most cases, anybody with a basic CS knowledge perfectly knows that no matter how much testing you do you can never be guaranteed that the code is correct by just testing it. Infact if the test is buggy too, it may generate false positives. The same way you _have_ verify any unit-test without using yet another unittest (or you enter an infinite recursion), you can also verify that the bugfix is correct in the first place. The idea that without an unittest isn't possible to verify the correctness of a bugfix is totally wrong. An unit-test is sure useful, but it shouldn't be mandatory for quick bugfixes. And the time that it would take to write a new unittest for a new bug, before deploying the fix in production, is definitely "wasted". 3) when I posted the ticket (again I received no answer with that one because of the trac hidden feature) about POLLHUP/ERR/NVAL core reactor troubles, I thought it wasn't strictly needed. But that was a few weeks ago if I remember well. In the last few weeks things changed and now it looks strictly needed and worst of all to be fully reliable I would need it in the client too, and on the client I still allow my users to use the standard twisted from twistedmatrix.com. I will probably have to workaround it with a timer but it's still not a desiderable solution since I will have to rearm the poll syscall for a little way in unblocking mode which is theoretically unsafe. 4) his belief that the core reactor limitation of point 3 "can be affected even without changing any external APIs" (btw, I guess with his native english he actually means "fixed" and not "affected") implies the external API won't change but I can guarantee you that the semantics will change in a not-backwards-compatible way. I think the users should know if you're going to make not-backwards compatible semantical changes in the core reactor without changing the external API (i.e. transport.pauseProducing and friends) so they can check their apps won't break. 5) about the technical things that I said about nevow, axiom and epsilon previously, I'm sorry if the divmod guys didn't like it, but if they're not true, then they should not get angry and insult me, but they should post benchmarks that invalidate my claims. They are very welcome to start to invalidate my bold claim that for rendering web2+cheetah is an order of magnitude faster (and in turn more scalable) than web+nevow. 6) about the performance of web2 vs apache/cherrypy (note: this is different from point 5, this is _not_ web2+cheetah vs web+nevow), there is no reason to worry about the channel of web2. No reason to change the API. I already told foom and drier privately. The benchmark I've seen posted to the list had a tiny size per page. Unfortunately the majority of the cpu time is spent in the twisted core (i.e. basically the reactor). I measured it. There's little or nothing you can do inside web2 to speedup the per-connection overhead. Infact if you increase the size of the page, the connections per second remain the same, only the bandwidth increases. So effectively web2 has no immediate performance issues because most pages are larger than a dozen bytes. When you do the test on a normal page size, things are ok. Most of the overhead happens in the handling of the socket outside web2, and it's very similar for twisted.web and it's a fixed cost outside web2. Again I will be totally happy to be proven wrong and see that the divmod folks can make web2 go much faster with a tiny page size with a change of API inside twisted/web2 directory and without touching the reactor code.

By the way, if having a sense of humor would mean enjoying reading doc/fun/Twisted.Quotes then I'd be proud to be humorless(tm). http://twistedmatrix.com/trac/browser/trunk/doc/fun/Twisted.Quotes?rev=16852...

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
And the time that it would take to write a new unittest for a new bug, before deploying the fix in production, is definitely "wasted".
I'm not a Twisted dev, but I do manage a couple open-source projects, and would like to point out: Participation in the open-source development process requires good communication skills. A unit test is an excellent way of communicating to the main developers that you've thought the problem through clearly and showed that your solution is a worthy one. Open-source developers are busy folk, so anything you can do to take their lives easier (even if you think their rules are foolish) will speed up the inclusion of your patch in the long run. Remember that the majority of Twisted developers are *volunteers*. I highly doubt that the time it would take for you to write a unit test would significantly impact *anyone* else who is using Twisted in production. - - Colin -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEbQyYXZxSS+Knk6ARAjB4AJ9VGy7lAb2v7qCnYz+JA4TNkXsDjACfX8pl FRmxo5loTbl7gNmP788vKTk= =bBaD -----END PGP SIGNATURE-----

On Fri, 2006-05-19 at 01:42 +0200, Andrea Arcangeli wrote: [snip. Not overly interested in the flamewar.]
2) verifying a bugfix correctness doesn't require unittests in most cases, anybody with a basic CS knowledge perfectly knows that no matter how much testing you do you can never be guaranteed that the code is correct by just testing it. Infact if the test is buggy too, it may generate false positives. The same way you _have_ verify any unit-test without using yet another unittest (or you enter an infinite recursion), you can also verify that the bugfix is correct in the first place. The idea that without an unittest isn't possible to verify the correctness of a bugfix is totally wrong. An unit-test is sure useful, but it shouldn't be mandatory for quick bugfixes. And the time that it would take to write a new unittest for a new bug, before deploying the fix in production, is definitely "wasted".
I don't believe you understand the purpose of unit testing. The approach you appear to be advocating leads to unmaintainable, buggy code. The unit test is developed to verify that the bug you believe exists does, in fact, exist. Buggy code will cause the test to fail, while correct code will cause the test to pass. If the behaviour you observe is actually caused by something else, your test will pass, but the behaviour will stay the same. In this way, you can correctly identify the cause of the problem. Then you can develop a patch. Importantly, once you have developed a patch, you can verify that it does, in fact, fix the problem. If the code passes your new unit test after you apply your patch, the patch is correct. If the test still fails, your patch doesn't, in fact, fix the problem. Additionally, when other changes are made in the future, the new unit test can be used to verify that those changes (like your patch) don't break existing code, ie: regression testing. I'm personally a big fan of this feature of test suites. Incidentally, those with slightly more CS knowledge know that it is possible, though by no means easy, to build a system that is provably correct. An investigation of the Z specification language may prove enlightening. I think you mean that a test suite proves that the system passes all the tests, not that it is bug free.
5) about the technical things that I said about nevow, axiom and epsilon previously, I'm sorry if the divmod guys didn't like it, but if they're not true, then they should not get angry and insult me, but they should post benchmarks that invalidate my claims. They are very welcome to start to invalidate my bold claim that for rendering web2+cheetah is an order of magnitude faster (and in turn more scalable) than web+nevow.
I think you have this backwards: those who make bold claims are the ones with the burden of proof. Simply claiming that something is so does not make it so. If you have benchmarks that demonstrate your claim, and importantly, the method used to generate them, then by all means share them with others. If your claims are true, this information will help in fixing the problem. Fixing these bugs is what we all want, after all. -- Justin Warren <daedalus@eigenmagic.com>

On Fri, May 19, 2006 at 10:41:35AM +1000, Justin Warren wrote:
break existing code, ie: regression testing. I'm personally a big fan of this feature of test suites.
I'm a big fun of test suites as well. I only disagree with wasting time delaying the integration of a valid bugfix just because the unit test doesn't exist yet. I absolutely never said unit tests are a waste of time. For the last months I've always said that "unit tests" are _welcome_ at the top of the cpushare-twisted webpage.
Incidentally, those with slightly more CS knowledge know that it is possible, though by no means easy, to build a system that is provably correct. An investigation of the Z specification language may prove enlightening. I think you mean that a test suite proves that the system passes all the tests, not that it is bug free.
What I mean is that a test suite cannot prove the code is bug free. Nor that any bugfix is correct. If nothing else because the test suite may be buggy too. This is obvious. Clearly a test suite is welcome and can only help, but its mandatory requirement for any change to the code sounds way excessive. I perfectly know about formal demonstrations being possible too (I spoke about those matters for a long time last year in a completely different context) but they're not unit-tests (certainly not the ones you see in the twisted reposistory), so I didn't mention this to avoid further confusion. I doubt it's feasible to demonstrate Twisted bug free formally (to back my guess I remind you Alan Cox quote saying twisted is a 6m unauditable weirdness, I guess he was partly joking though). http://article.gmane.org/gmane.linux.kernel/327172 My current worries are the troubles with poll, I worry about the lack of epoll, I worry about scaling in SMP with one thread per cpu. Those are the things that should be discussed instead of receiving emails from people about lack of unit tests for fixes that can be trivially verified by reading the code.
make it so. If you have benchmarks that demonstrate your claim, and importantly, the method used to generate them, then by all means share them with others. If your claims are true, this information will help in fixing the problem. Fixing these bugs is what we all want, after all.
About the benchmarks to make an example I posted some benchmarks here: http://twistedmatrix.com/pipermail/twisted-web/2006-January/002425.html I used the klive homepage for it. You can reproduce yourself downloading it (all GPL): http://klive.cpushare.com/downloads/ Older versions uses web+nevow, newer uses web2+Cheetah (I don't remember exactly the time of the switch but it's easy to find with some diff). However here the kind of the answers I got: http://twistedmatrix.com/pipermail/twisted-web/2006-January/002428.html So I didn't post more benchmarks, nor I tried to produce an official benchmark that is easier to run than to install klive locally. Also note, quite a lot of the time of klive is spent in the database. So it's one of the worst possible benchmarks for web1+nevow vs web2+cheetah since only little time is spent for the rendering. I measured much higher html delivery speedups in other pages that weren't asking the db such cpu intensive queries. If there is interest I can produce an official benchmark (that sounds much more useful than unit-tests for every bugfix). However I guess we'll have to follow the above advice and do it on the cpushare-twisted list. Also note, if you've a better place than cpushare-twisted for things that may not be welcome here, that's fine with me. I made up this cpushare-twisted things to fit my needs, only because I didn't find any other alternate place.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Andrea Arcangeli wrote:
On Fri, May 19, 2006 at 10:41:35AM +1000, Justin Warren wrote:
break existing code, ie: regression testing. I'm personally a big fan of this feature of test suites.
I'm a big fun of test suites as well. I only disagree with wasting time delaying the integration of a valid bugfix just because the unit test doesn't exist yet.
It has been my experience, that if a bug is "fixed", and there wasn't a unit test for the bug, then a unit test won't get written until someone breaks it again and spends potentially many man hours tracking down the the bug again. Unit tests don't just test that a bug is "fixed" they help to document the bug, to make it easier to fix when it is broken again (and a bug without a test will resurface) or if the original bug fix turns out to not be complete or entirely correct. And if your unit tests aren't more easily verifiably correct than your code is, you're either not writing very complex code or, to paraphrase jml, your unit tests aren't unit-y enough. It is also very difficult to judge the correctness of the code (and therefor the bug 'fix') if we can not reproduce the bug. It really isn't enough that we take your word for it that there is a bug. It's not that we don't trust you in particular (well ok, some of us are indifferent and have no opinion high or low about your skills as a programmer or CS student, (well mostly it's just me)) but humans make mistakes. In such a case, a unit test can quickly indicate that there is a bug, or that the submitter of the unit test has made a mistake. You seem to be under the impression that submitting a unit test with your patch means they will both be applied simultaneously and that we'll take the green [OK] from trial to indicate that everything is fine and dandy. I assure you this isn't the case, we actually will make sure the bug exists before we fix it. - -David - -- "Usually the protocol is this: I appoint someone for a task, which they are not qualified to do. Then, they have to fight a bear if they don't want to do it." -- Glyph Lefkowitz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (Darwin) iD8DBQFEbT9krsrO6aeULcgRAp31AJ9Z12bQi9aUr2nV97Zqb8+TijSZvwCcCZhD kT3p6umR6jK5Jy7/35q7etE= =NBEJ -----END PGP SIGNATURE-----

On Fri, 2006-05-19 at 05:04 +0200, Andrea Arcangeli wrote:
On Fri, May 19, 2006 at 10:41:35AM +1000, Justin Warren wrote:
break existing code, ie: regression testing. I'm personally a big fan of this feature of test suites.
I'm a big fun of test suites as well. I only disagree with wasting time delaying the integration of a valid bugfix just because the unit test doesn't exist yet. I absolutely never said unit tests are a waste of time. For the last months I've always said that "unit tests" are _welcome_ at the top of the cpushare-twisted webpage.
Righto. How do you know it's a valid bugfix without a test? Personally, I know that I make mistakes from time to time, so I think it's handy to have something that will independantly verify if I've made one or not. Many a time I've thought I knew what was broken only to find out it was something completely different. The twisted folks appear to disagree with you about the necessity of writing a unit test as part of the bugfix integration process. Since it's their code, they get to make the rules.
Incidentally, those with slightly more CS knowledge know that it is possible, though by no means easy, to build a system that is provably correct. An investigation of the Z specification language may prove enlightening. I think you mean that a test suite proves that the system passes all the tests, not that it is bug free.
What I mean is that a test suite cannot prove the code is bug free. Nor that any bugfix is correct. If nothing else because the test suite may be buggy too. This is obvious.
Obvious to you and me, perhaps, but there may be others who read this to whom it isn't so obvious. Hopefully they find this thread helpful.
Clearly a test suite is welcome and can only help, but its mandatory requirement for any change to the code sounds way excessive.
I guess we'll just have to agree to disagree on this point. I support the mandatory unit test requirement.
I perfectly know about formal demonstrations being possible too (I spoke about those matters for a long time last year in a completely different context) but they're not unit-tests (certainly not the ones you see in the twisted reposistory), so I didn't mention this to avoid further confusion. I doubt it's feasible to demonstrate Twisted bug free formally (to back my guess I remind you Alan Cox quote saying twisted is a 6m unauditable weirdness, I guess he was partly joking though).
My apologies for starting a thread derail. I was simply responding to your assertion that nothing can be proven to be bug free. Rather petty of me in hindsight.
My current worries are the troubles with poll, I worry about the lack of epoll, I worry about scaling in SMP with one thread per cpu. Those are the things that should be discussed instead of receiving emails from people about lack of unit tests for fixes that can be trivially verified by reading the code.
We disagree on the 'trivially verified by reading code' part. It is my opinion that only trivially simple code can be correctly verified simply by reading it, particularly by so fallible a human as myself. Perhaps your code reading skills are far superior to my own. Unit tests help me to understand other's code. I have enough trouble understanding my own code six months after writing it. As you suggest, perhaps now is the time to move on to discussing other issues? [snip benchmarking bits] Interesting reading. My apologies to everyone else on the list for contributing to the... clutter. -- Justin Warren <daedalus@eigenmagic.com>

On 5/19/06, Andrea Arcangeli <andrea@cpushare.com> wrote:
On Fri, May 19, 2006 at 10:41:35AM +1000, Justin Warren wrote:
break existing code, ie: regression testing. I'm personally a big fan of this feature of test suites.
I'm a big fun of test suites as well. I only disagree with wasting time delaying the integration of a valid bugfix just because the unit test doesn't exist yet. I absolutely never said unit tests are a waste of time. For the last months I've always said that "unit tests" are _welcome_ at the top of the cpushare-twisted webpage.
Incidentally, those with slightly more CS knowledge know that it is possible, though by no means easy, to build a system that is provably correct. An investigation of the Z specification language may prove enlightening. I think you mean that a test suite proves that the system passes all the tests, not that it is bug free.
What I mean is that a test suite cannot prove the code is bug free. Nor that any bugfix is correct. If nothing else because the test suite may be buggy too. This is obvious.
Clearly a test suite is welcome and can only help, but its mandatory requirement for any change to the code sounds way excessive.
Andrea, Your main objection is that requiring unit tests for bug fixes is excessive. I think it would be fair to say that you believe that following such a requirement means wasting time. Many people have defended this requirement. They have said that writing a test: - ensures the bug stays fixed - communicates important information about decisions in the code - provides a clear [and fast -- jml] way of reproducing the bug - confirms the existence of the bug You raised a concern that unit tests do not prove the absence of bugs. You have also stated that unit tests are desirable, but not necessary. I would like to respond to these points. First, although unit tests do not *prove* the absence of a bug, they provide strong evidence for its absence. When fixing code, there must be some check that the fix is correct. The check generally takes one of four forms: informal induction from the code; manual experimentation; automatic experimentation (i.e. unit tests) and formal verification. The first provides unacceptably weak evidence. The fourth proves the matter, but is too difficult to attempt for most bugs. This leaves the second and the third. I would consider either acceptable for demonstrating a bug's absence. Second, without unit tests the amount of work required to maintain code increases over time, and so they are necessary. Each of the advantages listed above has a corresponding disadvantage: the bug will probably appear again; decisions in code lie undocumented; bugs cannot be easily reproduced and so cannot be easily determined as either fixed or unfixed. Each disadvantage costs time. There is a finite supply of time and an arbitrarily large supply of bugs. If you wish to argue against our requirement for unit tests, then you must persuade us either that the evidence they provide is not strong enough to provide the listed benefits, or that the work in writing unit tests is significantly greater than the work of not writing unit tests. Regards, jml

On Fri, May 19, 2006 at 03:30:31PM +1000, Jonathan Lange wrote: [...]
provide strong evidence for its absence. When fixing code, there must be some check that the fix is correct. The check generally takes one of four forms: informal induction from the code; manual
I think often a combination of checks are used: in particular, reading the code and seeing that the fix "makes sense" in addition to an empiricial demonstration of absence (exercising the fixed bug manually or by automated test) is very common. A fix is rarely accepted if it doesn't "make sense", even if there's an automated test case that suggests it works. [...]
If you wish to argue against our requirement for unit tests, then you must persuade us either that the evidence they provide is not strong enough to provide the listed benefits, or that the work in writing unit tests is significantly greater than the work of not writing unit tests.
I think the problem may be different perspectives. For Andrea, he's apparently already manually verified that his patches solve the problems he's seen, so that's good enough. Ignoring for a moment the issue of what it takes to get it merged into official Twisted, further effort is wasted. For people maintaining Twisted, a once-off manual verification isn't enough, for the reasons you give. So for Andrea's fixes to make the leap from "good enough for him" to "good enough to be merged into Twisted", they need more work: they need automated tests. -Andrew.

On Thu, May 18, 2006 at 09:25:07PM +0200, Andrea Arcangeli wrote: [...]
Specifically I never said unittest are a waste of time, I only said that I don't have time to write unittests and that lack of unittests should not prevent valid bugfixes to be included and I think this is a very reasonable development approach. We can argue about features or huge changes, but I think valid bugfixes should not require unittests.
We, the people that have to *maintain* Twisted, think valid bugfixes require unittests. Our experience is that without them, bugs are doomed to reoccur and reoccur between releases as other bugs are "fixed" that we may as well not pretend to have fixed it in the first place. It's the same principle as commenting code and following cosmetic coding standards about whitespace. The presence of the test doesn't directly make the software more correct -- you could delete it and the code would still work exactly as it did with the test on the filesystem, and similarly ugly code and uncommented code isn't necessarily buggy code. But these things help maintainers applying patches and developers doing new work keep it correct, and avoid wasting their time wondering why an apparently innocuous change does something unexpected. And avoid wasting our time fixing the same bugs over and over again. This is why we are so strict about requiring tests with bug fixes. You might not have time to write the tests, but *we* don't have the time to deal with new code without tests, even if it is apparently more correct. Thus it is part of our coding standard now (although it hasn't been written down anywhere I'm aware of, you have certainly been told it is on many occasions). If you cannot follow the coding standards for a project, then don't be offended if that project doesn't apply your patches. -Andrew.

On Fri, May 19, 2006 at 11:47:54AM +1000, Andrew Bennetts wrote:
not have time to write the tests, but *we* don't have the time to deal with new code without tests, even if it is apparently more correct.
This is the bit I definitely disagree with.
If you cannot follow the coding standards for a project, then don't be offended if that project doesn't apply your patches.
I'm certainly not offended by it, but then I can't agree with a coding standard that I think is wrong. The thing I definitely agree with, is that having the unit test is certainly better than not having it, infact I'm very grateful to people like you that write unit tests, you're doing a great job.

On Thu, May 18, 2006 at 09:25:07PM +0200, Andrea Arcangeli wrote: [..]
But for all other patches I posted, they should be applied to everybody's own twisted copy. Including the "no it isn't", since the bug exists and needs fixing or I get exceptions.
Would you be so kind as to include details of these exceptions in your bug reports on trac next time? Having some extra detail would help us understand the circumstances of the apparent bug -- and help someone with some free time construct an automated test to replicate it. Also, I haven't seen anyone else report your bugs, and at least one of your bug reports has turned out to be quite wrong, so the extra information would help us to determine if the bug is really ours or perhaps a misunderstanding of yours of how to use Twisted (which in turn might be due to a documentation bug...). While I'm on the subject, it would have been good if you'd attached the patches directly in the bug reports in the first place, rather than pasting links that have since broken. Aside from being robust against you breaking your links, it follows the normal conventions the developers expect: i.e. that patches are in the bug report, where they're easy to find and automatically mailed to subscribers and whatnot. It saves us time, which gives us more time to actually fix things. In short: help us help you. A bug report consisting of a single sentence in the summary and a link to a patch isn't trying very hard to communicate with us about an issue you have presumably invested time in investigating and understanding. Why not share that research with us, so we don't have to duplicate your effort? (An example: http://twistedmatrix.com/trac/ticket/1661 is a poor bug report). I find it odd that you have so much time to debate our development methods on this mailing list, but apparently no time to try to communicate details about your bugs or discuss them. Seeing as you are so confident in telling us how we should spend our time, let me return the favour: you should spend more time explaining your bug reports. I'll note that a clearly written test case can be an adequate explanation... By the way, you can easily find your bugs in trac here: http://twistedmatrix.com/trac/search?q=andrea&ticket=on -Andrew.

On Wed, 17 May 2006 16:28:07 +0200, Andrea Arcangeli <andrea@cpushare.com> wrote:
Here a list of fixes present in CPUShare-Twisted mercurial tree and missing in Twisted SVN trunk. Most of these have been posted as a ticket in trac without feedback (by now the links in the tickets are obsolete due to bugs in tailor that required a rebuild of the SVN->HG repository, but nobody asked about the dangling link anyway). So I rensend them here just in case somebody is interested. I will not answer to replies because I've no time, sorry. Each email contains one patch.
If you had put patches into the issue tracker in the first place you wouldn't have had to resend anything at all.
This fixes a reentrance problem in connectionLost if invoked by shutdown at the same time as the real disconnect.
No it doesn't. Jean-Paul
participants (12)
-
Andrea Arcangeli
-
Andrew Bennetts
-
Colin McMillen
-
Cory Dodt
-
David Reid
-
glyph@divmod.com
-
James Y Knight
-
Jean-Paul Calderone
-
Johann Borck
-
Jonathan Lange
-
Justin Warren
-
Scott Lamb