[Twisted-Python] 9.0.0 question

Hi, I've switched recently from 8.2 to 9.0 and noticed that some of my client scripts hang in reactor.stop() on exit sometimes. That never happened before. For example if I run the gethostbyname.py from the twisted-names examples directory it prints the correct result and hangs forever until I press Cntrl-C. Then it prints the following traceback: terekhov@linux:/home/terekhov/python/twisted/9.0/Twisted-9.0.0/doc/names/examples line 181, in addCallbacks self._runCallbacks() --- <exception caught here> --- File "/usr/lib64/python2.5/site-packages/twisted/internet/defer.py", line 323, in _runCallbacks self.result = callback(self.result, *args, **kw) File "gethostbyname.py", line 12, in gotResult reactor.stop() File "/usr/lib64/python2.5/site-packages/twisted/internet/base.py", line 553, in stop "Can't stop reactor that isn't running.") twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running. terekhov@linux:/home/terekhov/python/twisted/9.0/Twisted-9.0.0/doc/names/examples
At the same time echo client/server example from the twisted core works as expected. Any hint would be appreciated. BTW I use SuSE 11.0 on x86_64 with python 2.5.2 Regards, -- Mikhail Terekhov

On Jan 20, 2010, at 3:20 PM, Mikhail Terekhov wrote:
I don't see the behavior you describe, but I do see this traceback on trunk with every 3rd run or so of that example - maybe the example is buggy? doc/names/examples$ python gethostbyname.py twistedmatrix.com twisted/names/dns.py:1670: DeprecationWarning: Please only pass IPs to write(), not hostnames self.transport.write(message.toStr(), address) Traceback (most recent call last): File "twisted/internet/udp.py", line 121, in doRead self.protocol.datagramReceived(data, addr) File "twisted/names/dns.py", line 1700, in datagramReceived d.callback(m) File "twisted/internet/defer.py", line 239, in callback self._startRunCallbacks(result) File "twisted/internet/defer.py", line 308, in _startRunCallbacks self._runCallbacks() --- <exception caught here> --- File "twisted/internet/defer.py", line 324, in _runCallbacks self.result = callback(self.result, *args, **kw) File "twisted/names/common.py", line 239, in <lambda> ).addBoth(lambda passthrough: (r.protocol.transport.stopListening(), passthrough)[1]) exceptions.AttributeError: 'NoneType' object has no attribute 'stopListening' Can you provide a simpler, more streamlined example of the problem you're describing?

On 03:43 am, glyph@twistedmatrix.com wrote:

On Thu, Jan 21, 2010 at 3:58 AM, <exarkun@twistedmatrix.com> wrote:
I think I found it, it is somewhat different IMHO. When you run python gethostbyname.py localhost notice the '''localhost''' there, the getHostByName('localhost') returns defer.succeed(..) so the callback gotResult and hence reactor.stop() is called even before reactor is run and for some reason it hangs there inside reactor.stop(). So there are actually two points here: 1. the gethostbyname.py example should probably be changed something like this --- gethostbyname.py.orig 2010-01-21 10:01:30.000000000 -0500 +++ gethostbyname.py 2010-01-21 10:02:55.000000000 -0500 @@ -15,7 +15,9 @@ failure.printTraceback() reactor.stop() -d = client.getHostByName(sys.argv[1]) -d.addCallbacks(gotResult, gotFailure) +def main(): + d = client.getHostByName(sys.argv[1]) + d.addCallbacks(gotResult, gotFailure) +reactor.addSystemEventTrigger("after", "startup", main) reactor.run() 2. Why reactor.stop() hangs if it is called before reactor.run()? Are they worth a tickets? Regards, -- Mikhail Terekhov

On 21 Jan, 03:30 pm, termim@gmail.com wrote:
This sounds a lot like another example of the problem described in <http://twistedmatrix.com/trac/ticket/3270>.
[snip]
2. Why reactor.stop() hangs if it is called before reactor.run()?
It doesn't. It raises an exception. The reason the example hangs is that since reactor.stop() was called before reactor.run(), it's not called *after* reactor.run(). So the reactor never stops. Jean-Paul

On Fri, Jan 22, 2010 at 4:40 PM, <exarkun@twistedmatrix.com> wrote:
Care to elaborate? Who hangs then and why python exits and I see this exception only after I hit Cntl-C? Actually I noticed this problem in my old wxPython/Twisted application. Before upgrade everything was sweet and shiny but when I upgraded Twisted to 9.0 my application suddenly started to hang on exit. BTW I use wxreactor and install it exactly as in doc/core/examples/wxdemo.py It is interesting that doc/core/examples/wxacceptance.py has no such a problem, but doc/core/examples/wxdemo.py has! If I start it, wait till it prints to stdout "two seconds passed" and then try to quit it either by File->Exit or by clicking on the WM close button it does not respond, even if I hit Cntrl-C in the terminal from where I run it, but if after Cntrl-C I go to the File->Exit it quits after printing "Received SIGINT, shutting down." terekhov@_:~/Twisted-9.0.0/doc/core/examples >python wxdemo.py 2010-01-22 17:16:03-0500 [-] Log opened. 2010-01-22 17:16:05-0500 [-] two seconds passed ^C ^C 2010-01-22 17:21:03-0500 [-] Received SIGINT, shutting down. terekhov@_:~/Twisted-9.0.0/doc/core/examples > Another clue is that if I'm fast enough and can click on the close button _before_ it prints "two seconds passed", then everything is fine and it quits without problem: terekhov@_:~/Twisted-9.0.0/doc/core/examples >python wxdemo.py 2010-01-22 17:23:59-0500 [-] Log opened. 2010-01-22 17:24:01-0500 [-] two seconds passed terekhov@_:~/Twisted-9.0.0/doc/core/examples > On the same note may be doc/core/examples/wxacceptance.py has no such a problem because it uses reactor.callLater(0.1,helloWorld)? I used gethostbyname.py as an example only because it is much smaller and the behavior is very similar. May be it is something different.
since reactor.stop() was called before reactor.run(), it's not called *after* reactor.run(). So the reactor never stops.
That is nice :) Regards, -- Mikhail Terekhov

On 10:42 pm, termim@gmail.com wrote:
I think that's what I explained in the rest of the sentence that is cut off above. You may only see the exception reported later on because the example is relying on garbage collection for that reporting.
This sounds familiar. I think wxreactor has some wake-up issues. It's not a very reliable reactor. wxPython differs in various ways on different platforms and from release to release in ways which wxreactor doesn't account for. I think the problem with the dns example is probably not related to your wxreactor issues at all. Jean-Paul

On Sat, Jan 23, 2010 at 1:40 AM, Mikhail Terekhov <termim@gmail.com> wrote:
So why reactor never stops if it was never run? What it is doing?
You call reactor.stop(); this does nothing but produce a delayed exception. You then call reactor.run(), which runs the reactor. You then never call reactor.stop() again, and thus the reactor continues running forever. -- mithrandi, i Ainil en-Balandor, a faer Ambar

On Jan 20, 2010, at 3:20 PM, Mikhail Terekhov wrote:
I don't see the behavior you describe, but I do see this traceback on trunk with every 3rd run or so of that example - maybe the example is buggy? doc/names/examples$ python gethostbyname.py twistedmatrix.com twisted/names/dns.py:1670: DeprecationWarning: Please only pass IPs to write(), not hostnames self.transport.write(message.toStr(), address) Traceback (most recent call last): File "twisted/internet/udp.py", line 121, in doRead self.protocol.datagramReceived(data, addr) File "twisted/names/dns.py", line 1700, in datagramReceived d.callback(m) File "twisted/internet/defer.py", line 239, in callback self._startRunCallbacks(result) File "twisted/internet/defer.py", line 308, in _startRunCallbacks self._runCallbacks() --- <exception caught here> --- File "twisted/internet/defer.py", line 324, in _runCallbacks self.result = callback(self.result, *args, **kw) File "twisted/names/common.py", line 239, in <lambda> ).addBoth(lambda passthrough: (r.protocol.transport.stopListening(), passthrough)[1]) exceptions.AttributeError: 'NoneType' object has no attribute 'stopListening' Can you provide a simpler, more streamlined example of the problem you're describing?

On 03:43 am, glyph@twistedmatrix.com wrote:

On Thu, Jan 21, 2010 at 3:58 AM, <exarkun@twistedmatrix.com> wrote:
I think I found it, it is somewhat different IMHO. When you run python gethostbyname.py localhost notice the '''localhost''' there, the getHostByName('localhost') returns defer.succeed(..) so the callback gotResult and hence reactor.stop() is called even before reactor is run and for some reason it hangs there inside reactor.stop(). So there are actually two points here: 1. the gethostbyname.py example should probably be changed something like this --- gethostbyname.py.orig 2010-01-21 10:01:30.000000000 -0500 +++ gethostbyname.py 2010-01-21 10:02:55.000000000 -0500 @@ -15,7 +15,9 @@ failure.printTraceback() reactor.stop() -d = client.getHostByName(sys.argv[1]) -d.addCallbacks(gotResult, gotFailure) +def main(): + d = client.getHostByName(sys.argv[1]) + d.addCallbacks(gotResult, gotFailure) +reactor.addSystemEventTrigger("after", "startup", main) reactor.run() 2. Why reactor.stop() hangs if it is called before reactor.run()? Are they worth a tickets? Regards, -- Mikhail Terekhov

On 21 Jan, 03:30 pm, termim@gmail.com wrote:
This sounds a lot like another example of the problem described in <http://twistedmatrix.com/trac/ticket/3270>.
[snip]
2. Why reactor.stop() hangs if it is called before reactor.run()?
It doesn't. It raises an exception. The reason the example hangs is that since reactor.stop() was called before reactor.run(), it's not called *after* reactor.run(). So the reactor never stops. Jean-Paul

On Fri, Jan 22, 2010 at 4:40 PM, <exarkun@twistedmatrix.com> wrote:
Care to elaborate? Who hangs then and why python exits and I see this exception only after I hit Cntl-C? Actually I noticed this problem in my old wxPython/Twisted application. Before upgrade everything was sweet and shiny but when I upgraded Twisted to 9.0 my application suddenly started to hang on exit. BTW I use wxreactor and install it exactly as in doc/core/examples/wxdemo.py It is interesting that doc/core/examples/wxacceptance.py has no such a problem, but doc/core/examples/wxdemo.py has! If I start it, wait till it prints to stdout "two seconds passed" and then try to quit it either by File->Exit or by clicking on the WM close button it does not respond, even if I hit Cntrl-C in the terminal from where I run it, but if after Cntrl-C I go to the File->Exit it quits after printing "Received SIGINT, shutting down." terekhov@_:~/Twisted-9.0.0/doc/core/examples >python wxdemo.py 2010-01-22 17:16:03-0500 [-] Log opened. 2010-01-22 17:16:05-0500 [-] two seconds passed ^C ^C 2010-01-22 17:21:03-0500 [-] Received SIGINT, shutting down. terekhov@_:~/Twisted-9.0.0/doc/core/examples > Another clue is that if I'm fast enough and can click on the close button _before_ it prints "two seconds passed", then everything is fine and it quits without problem: terekhov@_:~/Twisted-9.0.0/doc/core/examples >python wxdemo.py 2010-01-22 17:23:59-0500 [-] Log opened. 2010-01-22 17:24:01-0500 [-] two seconds passed terekhov@_:~/Twisted-9.0.0/doc/core/examples > On the same note may be doc/core/examples/wxacceptance.py has no such a problem because it uses reactor.callLater(0.1,helloWorld)? I used gethostbyname.py as an example only because it is much smaller and the behavior is very similar. May be it is something different.
since reactor.stop() was called before reactor.run(), it's not called *after* reactor.run(). So the reactor never stops.
That is nice :) Regards, -- Mikhail Terekhov

On 10:42 pm, termim@gmail.com wrote:
I think that's what I explained in the rest of the sentence that is cut off above. You may only see the exception reported later on because the example is relying on garbage collection for that reporting.
This sounds familiar. I think wxreactor has some wake-up issues. It's not a very reliable reactor. wxPython differs in various ways on different platforms and from release to release in ways which wxreactor doesn't account for. I think the problem with the dns example is probably not related to your wxreactor issues at all. Jean-Paul

On Sat, Jan 23, 2010 at 1:40 AM, Mikhail Terekhov <termim@gmail.com> wrote:
So why reactor never stops if it was never run? What it is doing?
You call reactor.stop(); this does nothing but produce a delayed exception. You then call reactor.run(), which runs the reactor. You then never call reactor.stop() again, and thus the reactor continues running forever. -- mithrandi, i Ainil en-Balandor, a faer Ambar
participants (4)
-
exarkun@twistedmatrix.com
-
Glyph Lefkowitz
-
Mikhail Terekhov
-
Tristan Seligmann