[Twisted-Python] wxpython issues

Shawn Church twisted-python at twistedmatrix.com
Thu Apr 14 23:13:34 MDT 2005


I am new to twisted and also experienced problems using wxreactor.  After
reading some earlier posts to this message list I wrote a wx.App sub-class
that polls the reactor ONLY when the GUI requires data from twisted:

# This is a method of derived wx.App class I'm leaving out init/clean up
methods:
def twistedCall(self,deferredFunction,timeOut=3.0):
""" Call a remote method and return when it is done (or times out) """
   class WaitForDeferred(object):
      def __call__(self,deferredFunction,timeOut=3.0):
         self.loop=True; self.returnValue=None
         deferredFunction().addBoth(self.__callback)
         if timeOut>0:
            self.timeOut=reactor.callLater(
               timeOut,self.__callback,
               Failure("Timeout while connecting to host",TimeoutError)
            )
         else: self.timeOut=None

         while self.loop:
            reactor.runUntilCurrent();
            reactor.iterate(0)

         if isinstance(self.returnValue,Failure):
            self.returnValue.trap()
	 return self.returnValue

      def __callback(self,arg):
         if self.timeOut is not None: self.timeOut.cancel()
         self.timeOut=None; self.returnValue=arg; self.loop=False

   try:
      return WaitForDeferred()(deferredFunction,timeOut)
   # This is to reconnect to server after the connection is broken (client
factory               is overridden to
        # reconnect as well)  Is there a better way of doing this???:
   except pb.DeadReferenceError:
      self.twistedPerspective=self.twistedCall(lambda:
         self.twistedFactory.login(self.twistedCredentials)
      )
      return WaitForDeferred()(deferredFunction,timeOut)

So when the application needs to login,  request data,  etc.,  it calls
wx.GetApp().twistedCall(...) and the wx app is "blocked" until  the deferred
completes.  In addition I have a wx.Timer poll set at one second to do one
reactor iteration "just in case" although things seem to run fine without this
extra poll.

In preliminary tests I was able to run 10+ client instances each requesting
551k blocks of data at 1 second intervals and everything seemed to run fine
(some of the wx polls were missed but twisted never dropped anything).  Note
that this is a PB based client/server application running (both clients and
sever) on a 1.7 Ghz P4 w/1 GB under Linux.

I was pretty impressed with this performance esp. since the server was reading
the 551k from disk each time it was requested with a simple "return
file(read(...))" statement and I did not even wrap the server code in a
deferred like I should of.  I did this test to see if the the reactor loop,
as implemented,  would "starve" and drop data producing timeout errors.

This testing was done before I read this latest post and before any actual
production application code has been developed.  So am I better off just
scrapping this approach and adopting a threaded method?  The reason I adopted
the above approach was that, in general,  the applications I write NEED to
wait for data before they can continue.  For example,  the user enter a userid
and password and hits the "login" button. No further (interactive) processing
can be performed until the server validates the input and authorizes/rejects
the login.

I have over 20 years applications exp but minimal networking/systems type exp
so forgive me if my questions (and testing approach) are naive.  Also,  I
apologize for the length of this post. I tried to avoid posting so much code
but could not find a better way to explain what I was doing (I will be happy
to provide complete examples if anyone is interested).



Shawn Church
Information Systems Consultant
sl_church at sbcglobal.net
http://SChurchComputers.com


Uwe C. Schroeder (uwe at oss4u.com) wrote:
>
> You probably better switch to using separate threads.
> Although I basically invented the timer driven "eventloop starving" quite a
> while ago, published it in the python cookbook (which eventually was turned
> into wxreactor by Itamar), I meanwhile switched my application to multiple
> threads. Works way better, particularly on windows.
> The timer-eventloop works fine for smaller applications with little to
> moderate network usage, the moment you start transferring more data over the
> network you basically starve both eventloops to death, because neither of the
> loops gets enough CPU attention to do the job properly.
>
> You might want to check out this example:
>
>  http://solipsis.netofpeers.net/wiki/wikka.php?wakka=WxTwistedExample
>
> It's a basic example of multiple threads, but it will give you the idea.
> I've written a network wrapper layer to make this whole thing more easy to
> handle, but I can't put this online just yet (contract reasons) - and it's
> very specialized for my application anyways.  Just to give you a hint: once
> you understood how the above example works, you can write wrapper classes for
> the remote referenceable interfaces of twisted. This allows you to use the
> twisted interface the way it's documented without having to fiddle around
> with the threads.
>
> Hope that gives you some clues
>
> UC
>
>
>
> On Wednesday 13 April 2005 19:58, Anthony Baxter wrote:
> > The problem has been that wx's timer promises "no worse
> > than 1s" resolution. In practice, it's been utterly unable to
> > hit less than 100ms on Windows, and 20ms on Linux is a
> > sometimes-thing. The only real solution that works robustly
> > is to run wx and twisted in separate threads. If there's a new
> > version of wx, you should probably try running wxreactor with
> > a LoopingCall set to 1ms, and see what timer it can hit
> > reliably.
> >
> > Anthony
>
> --
> Open Source Solutions 4U, LLC	2570 Fleetwood Drive
> Phone:  +1 650 872 2425		San Bruno, CA 94066
> Cell:   +1 650 302 2405		United States
> Fax:    +1 650 872 2417
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>





More information about the Twisted-Python mailing list