[Twisted-Python] Twisted, wxPython & PyPubSub
gabriel.rossetti at arimaz.com
Thu Sep 10 09:47:15 EDT 2009
exarkun at twistedmatrix.com wrote:
> On 9 Sep, 07:12 am, gabriel.rossetti at arimaz.com wrote:
>> exarkun at twistedmatrix.com wrote:
>>> On 02:21 pm, gabriel.rossetti at arimaz.com wrote:
>>>> Hello everyone,
>>>> I am using wx with twisted and pubsub (not the on in wx but the
>>>> independent one) to notify each one of what is going on. I was
>>>> if I should use reactor.callFromThread to call publisher.sendMessage
>>>> not? I haven't been doing that until now but I wondered if it was
>>>> better to.
>>> Use reactor.callFromThread if you have code running in a non-reactor
>>> thread and you want it to initiate some action in the reactor thread.
>>> So, if publisher.sendMessage is using Twisted APIs or otherwise
>>> that it be run only in the reactor thread, and you need to use it from
>>> non-reactor thread, then use reactor.callFromThread. Otherwise,
>> Would you consider the wxreactor like a non-reactor thread?
> I'm not sure what you mean. The "reactor thread" is the thread that
> "reactor.run()" is called in. Even if you're using wxreactor.
>> I haven't
>> checked out the code behind PyPubSub, but it's basically the
>> Observer-Pattern so when I call publisher.sendMessage(...) it iterates
>> the "subscribers" (observers) and calls the functions they associated
>> the subscription. Those functions are both in the twisted code and the
>> wx code. The Twisted code sends messages nd the wx code brings-up/hides
>> dialogs or frames. In the wxdemo it does :
>> # look, we can use twisted calls!
>> reactor.callLater(2, self.twoSecondsPassed)
>> but doesn't use reactor.callFromThread, but unless I'm wrong
>> reactor.callLater does the same thing but deferred in time. I often see
>> reactor.callLater(0, myFunc) being used.
> The wx demo doesn't do anything with threads, so it doesn't need to use
> callFromThread. So, if you're only doing things like what the wx demo
> does, you probably don't need callFromThread either.
> callLater doesn't do the same thing as callFromThread. There might be
> some vague similarities (really the only one is that neither one calls
> the function you pass it right away), but they're for very different
Ok, well, from looking into the twisted source, it looks like the wx
main loop is run in a seperate thread
If this is correct, I don't think I can just call a function from the
twisted code that will in turn call a function in the wx code anytime,
because the wx event loop will be busy doing something else. It is the
same the other way around, here is an example :
the user clicks on a button, this calls
publisher.sendMessage("notify.server", button.name). The twisted code
registered to receive this event and so did the wx code. The twisted
code registered a callback that formats a message and sends it to the
server, the wx code updates the status to "pending" on the gui. When the
answer arrives from the server, this time the twisted code calls
publisher.sendMessage("server.response", res) and wx had registered to
receive this event to update the status to something else.
Now, since publisher.sendMessage() was called from wx, and from what I
understand from the WxReactor class code it runs in a thread, then the
callback on the twisted side should use reactor.callFromThread()
shouldn't it (since it was called from a different thread), but not the
callback in the wx code since it was called from the wx code? And when
publisher.sendMessage() is called from twisted code, shouldn't I do the
same, that is the callback in the twisted is just called and the
callback in the wx code is called with wx.CallLater() (to schedule it's
call in the main loop)?
More information about the Twisted-Python