Opened 10 years ago

Closed 10 years ago

#5272 defect closed worksforme (worksforme)

In the core doc, do not call reactor.stop directly in processEnded

Reported by: David Kao Owned by:
Priority: normal Milestone:
Component: core Keywords:
Cc: David Kao Branch:
Author:

Description (last modified by Jean-Paul Calderone)

I modeled the following code after the "verbose example" at

http://twistedmatrix.com/documents/current/core/howto/process.html#auto5

from twisted.internet import reactor, protocol

class OneRun(protocol.ProcessProtocol):
        def processEnded(self, reason):
                print "Process ended\n"
                reactor.stop()

def main():
        reactor.spawnProcess(OneRun(), executable="echo", args=["echo", "hello"], childFDs={0:0, 1:1, 2:2})
        reactor.run()

if __name__ == '__main__':
        main()

But it raises the exception "twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running." inside processEnded

It would seem one should not call reactor.stop inside processEnded. Calling reactor.callLater(0, reactor.stop) is fine.

The documentation is misleading and should be fixed.

Change History (8)

comment:1 Changed 10 years ago by Jean-Paul Calderone

Description: modified (diff)

Fixing description markup

comment:2 Changed 10 years ago by Jean-Paul Calderone

Resolution: worksforme
Status: newclosed

I'm unable to reproduce the error using Twisted trunk@HEAD on Ubuntu Karmic with Python 2.6:

exarkun@boson:/tmp$ cat example.py 
from twisted.internet import reactor, protocol

class OneRun(protocol.ProcessProtocol):
        def processEnded(self, reason):
                print "Process ended\n"
                reactor.stop()

def main():
        reactor.spawnProcess(OneRun(), executable="echo", args=["echo", "hello"], childFDs={0:0, 1:1, 2:2})
        reactor.run()

if __name__ == '__main__':
        main()
exarkun@boson:/tmp$ python example.py 
hello
Process ended

exarkun@boson:/tmp$ 

comment:3 Changed 10 years ago by Glyph

dkdog, if this is a problem, it's not a documentation problem. processEnded is a totally valid place to call reactor.stop and if it doesn't work we should fix it. If you can, please provide more details about your configuration so that we can reproduce the issue.

comment:4 in reply to:  3 Changed 10 years ago by David Kao

Replying to glyph:

dkdog, if this is a problem, it's not a documentation problem. processEnded is a totally valid place to call reactor.stop and if it doesn't work we should fix it. If you can, please provide more details about your configuration so that we can reproduce the issue.

I copied/pasted the code from this ticket again and ran the following:

[root@vpn1 code]# python ticket5272.py hello Process ended

unexpected error in processEnded Traceback (most recent call last):

File "/usr/local/lib/python2.7/site-packages/twisted/internet/process.py", line 714, in init

registerReapProcessHandler(self.pid, self)

File "/usr/local/lib/python2.7/site-packages/twisted/internet/process.py", line 66, in registerReapProcessHandler

process.processEnded(status)

File "/usr/local/lib/python2.7/site-packages/twisted/internet/_baseprocess.py", line 48, in processEnded

self.maybeCallProcessEnded()

File "/usr/local/lib/python2.7/site-packages/twisted/internet/process.py", line 916, in maybeCallProcessEnded

_BaseProcess.maybeCallProcessEnded(self)

--- <exception caught here> ---

File "/usr/local/lib/python2.7/site-packages/twisted/internet/_baseprocess.py", line 60, in maybeCallProcessEnded

proto.processEnded(Failure(reason))

File "ticket5272.py", line 6, in processEnded

reactor.stop()

File "/usr/local/lib/python2.7/site-packages/twisted/internet/base.py", line 571, in stop

"Can't stop reactor that isn't running.")

twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running. [root@vpn1 code]# cat /etc/redhat-release CentOS release 5.4 (Final) [root@vpn1 code]# uname -a Linux vpn1 2.6.18-164.el5xen #1 SMP Thu Sep 3 04:03:03 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux [root@vpn1 code]# python -V Python 2.7.1 [root@vpn1 code]#

My Centos is a virtual machine. The same exception occurs under both the following virtualization environment:

1) XenServer 5.6 2) VMware Workstation 6.5.2 under Windows 7 64bit

I think my XenServer is running in that paravirtualized mode with Intel's VT-x enabled. But the VMware under windows should be using a different mode. I am a bit fuzzy on these terms but I don't think level that deep down matters here.

Huh, I just tried the same, on another 64bit virtual machine, running Centos (but) 5.5 , on Rackspace's cloud server. Also Python 2.7.1. The code is fine. So, OS/hardware stuff could change all this? I am an average programmer, so I would be avoiding calling reactor.stop for now.

--- super tangential stuff that I just wanna bring up to bounce ideas after seeing that OS/hardware seems to matter ---

Okay ... I have had experience with buildbot that dies under virtualization environment b/c time would jump around. Because Centos 5.2 kernel defaults to 1000hz for ticks. After reducing ticks to 100hz (default for other linux kernels), the same Centos 5.2 is fine. NTP sync, etc alone don't solve it unless the ticks are reduced. This is very microscopic time shifting that humans don't see.

I hope twisted reactor isn't using any kind of time based stuff here. I would assume everything is sequential ...

Okay, I am really going very offtrack here. Don't even know if that was even related.

comment:5 Changed 10 years ago by David Kao

Cc: David Kao added

Just be aware whitelines are kinda messed up here but in the email it looks fine.

comment:6 Changed 10 years ago by Jean-Paul Calderone

Please read WikiFormatting.

comment:7 Changed 10 years ago by David Kao

Resolution: worksforme
Status: closedreopened

I just found out that reactor.spawnProcess could spawn the subprocess right away before reactor.run is executed.

I get the impression that most stuff don't get run until the reactor event loop is up and running with reactor.run()

In this case, who's answering all the ProcessProtocol's methods like processEnded then, without an event loop?

Could someone take a look and make a judgment call whether:

1) this is how it should be (like the programmer should carefully code and work around this, perhaps with an extra callLater wrapped around spawnProcess) (and like, reactor can also be used as a quick and dirty way to spawn subprocess, disregarding reactor as a crucial component of the twisted framework)

2) we should improve documentation?

3) or this is actually a bug?

comment:8 Changed 10 years ago by Jean-Paul Calderone

Resolution: worksforme
Status: reopenedclosed

I just found out that reactor.spawnProcess could spawn the subprocess right away before reactor.run is executed.

This doesn't seem related to this ticket.

I get the impression that most stuff don't get run until the reactor event loop is up and running with reactor.run()

That's true. Most stuff.

In this case, who's answering all the ProcessProtocol's methods like processEnded then, without an event loop?

The process starting is different from ProcessProtocol methods being called. ProcessProtocol.processEnded is not called until the reactor is running.

Further discussion should be moved to the mailing list. Thanks.

Note: See TracTickets for help on using tickets.