[Twisted-Python] oddness in gtk reactor compred to wx and plain reactor
Hi, I have been experience a weird problem with the gtk reactor. I've got a simple test case which seems to reproduce the problem, so I'm checking with the mailing list to understand if everything is going on properly. Here's the test code. I wasn't sure whether the log. calls are thread-safe, but I've noticed the same problem with Python's logging package. Using the wxPython or plain reactor seems to work as expected: messages from the TestThingy are spewed at about 0.1/sec, while with gtk, messages only come every 2 seconds if at all. import time, sys, logging from twisted.internet import gtk2reactor gtk2reactor.install() ## from wxPython.wx import * ## from twisted.internet import wxsupport from twisted.internet import reactor from twisted.python import threadable threadable.init() from twisted.python import log log.startLogging(sys.stdout) from twisted.internet import app from twisted.manhole import telnet from twisted.application import strports ## For testing with wx reactor ## class myWxApp(wxApp): ## def OnInit(self): ## return True ## mywxAppInstance = myWxApp(0) ## wxsupport.install(mywxAppInstance) class TestThingy: def __init__(self): log.err("TestThingy created") def run(self): log.err("TestThingy run") for i in range(10): log.err("TestThingy message") time.sleep(0.1) log.err("TestThingy done") class ThingyManager: def __init__(self): log.err("ThingyManager") def submitThingy(self): log.err("ThingyManager submitting") f = TestThingy() log.err("ThingyManager created") reactor.callInThread(f.run) log.err("ThingyManager calledInThread") def timer(*args): log.err("Timer: %d" % time.time()) reactor.callLater(1, timer) log.err("Starting") t = ThingyManager() log.err("Starting timer") reactor.callLater(0, timer) log.err("Submitting transfer") reactor.callLater(3, t.submitThingy) log.err("Running reactor") reactor.run() ## for starting the wx reactor ##reactor.run(installSignalHandlers=0) log.err("Reactor done")
Don't do time.sleep() in the main Twisted thread. This totally blocks *all* twisted code as twisted is single threaded, making scheduled events run late, network events not be handled, etc..
Itamar Shtull-Trauring wrote:
Don't do time.sleep() in the main Twisted thread. This totally blocks *all* twisted code as twisted is single threaded, making scheduled events run late, network events not be handled, etc..
Hi Itamar, I'm actually only calling time.sleep() from other than the main thread- TestThingy is the only routine that calls time.sleep, and it only does so when run from another thread via callInThread I should point out a few more details: 1) The problem only occurs with the gtk reactor, not the wx or plain reactors. It happens if I actually make a gtk GUI widget, or even if I don't. 2) The problem occurs even if I don't use time.sleep()-- anything exhibits the behavior (this is just to demonstrate the example) 3) If I hit control-C in the console about half-way through the test, it starts work normally- gtk.main() caches the signal, quits, and then the plain reactor seems to engage (???) I'm pretty sure my example (posted again below) is a valid one, can you please take a closer look? import time, sys, logging from twisted.internet import gtk2reactor gtk2reactor.install() ## for testing with the wx reactor ## from wxPython.wx import * ## from twisted.internet import wxsupport from twisted.python import threadable threadable.init() from twisted.internet import reactor from twisted.python import log log.startLogging(sys.stdout) from twisted.internet import app from twisted.manhole import telnet from twisted.application import strports ## class MyFrame(wxFrame): ## def __init__(self, parent, ID, title): ## wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(300, 200)) ## menu = wxMenu() ## menu.Append(wxID_EXIT, "E&xit", "Terminate the program") ## menuBar = wxMenuBar() ## menuBar.Append(menu, "&File"); ## self.SetMenuBar(menuBar) ## EVT_MENU(self, wxID_EXIT, self.DoExit) ## def DoExit(self, event): ## self.Close(true) ## reactor.stop() ## class myWxApp(wxApp): ## def OnInit(self): ## frame = MyFrame(NULL, -1, "Hello, world") ## frame.Show(true) ## self.SetTopWindow(frame) ## return true class TestThingy: def __init__(self): log.err("TestThingy created") def run(self): log.err("TestThingy run") for i in range(10): log.err("TestThingy message") time.sleep(0.1) log.err("TestThingy done") class ThingyManager: def __init__(self): log.err("ThingyManager") def submitThingy(self): log.err("ThingyManager submitting") f = TestThingy() log.err("ThingyManager created") reactor.callInThread(f.run) log.err("ThingyManager calledInThread") def timer(*args): log.err("Timer: %d" % time.time()) reactor.callLater(1, timer) log.err("Starting") t = ThingyManager() log.err("Starting timer") reactor.callLater(0, timer) log.err("Submitting transfer") reactor.callLater(3, t.submitThingy) log.err("Running reactor") reactor.run() ## for starting the wx reactor ## mywxAppInstance = myWxApp(0) ## wxsupport.install(mywxAppInstance) ## reactor.run(installSignalHandlers=0) log.err("Reactor done")
Hi, I tried to use the ReconnectingClientFactory for reconnecting purpose. I found that if the protocol was connected by my ethernet, and got lost later on by pulling out my ethernet cable, I couldn't get successful reconnection through my newly enabled wireless card. However, if I put the cable back and enable ethernet card, it reported success. Is this a feature or a bug? Why? Thank you! -- Yun
participants (3)
-
David E. Konerding
-
Itamar Shtull-Trauring
-
Yun Mao