[Twisted-Python] RE: how to create state machines?
Doug Farrell
dfarrell at mypublisher.com
Mon Mar 30 09:10:48 MDT 2009
Hi Andrew,
>
> Hi Doug:
>
> >This state machine initializes a system, issues an asynchronous
> command
> >that takes time to complete (say a motor move command) and then waits
> >for that command to be done before exiting. In the context of a
> >framework that is calling this state machine, the WAITCMD1 is
executed
> >repeatedly (polling) while the asynchronous command completes. A
> system
> >can be constructed with lots of little state machines like this and
be
> >made to look like it is doing many things at once even though the
> >execution of the program is single threaded.
>
> >I understand (pretty much) the Twisted framework is like this and
> >implmenting event handlers like connectionMade(), etc., is a state
> >machine, but I'm wondering how to implement what I've outlined above
> in
> >one of Twisted's state event handlers, or inside something like
> >callLater(). For example, let's say I want to use Twisted to run a
> long
> >running daemon process that has an XMLRPC interface. That XMLRPC
> >interface is an interface to a state machine inside Twisted that
> allows
> >the caller to change state, or start new state machines, or get the
> >status of a running state machine. In that case I'm thinking I want a
> >state machine the runs continuously in the Twisted loop, structured
> like
> >the example above; co-operatively yielding back to Twisted, but
> running
> >non-stop. Something like callLater(1, stateMachine), but non-stop,
> >without even the 1 second call loop.
>
> If I understand your correctly, I don't think you need to implement a
> state machine to simulate concurrency with Twisted - Twisted does a
lot
> of that for you. You can think of a Twisted application as a state
> machine - the callback being the state and the completion of the
> operation and the calling of the callback is the transition. These
> callbacks at runtime act like a thread of execution.
>
> def Initialize(...):
> # do something
> deferred = someFunctionThatReturnsADeferred()
> deferred.addCallback(State2)
>
> def State2(...):
> # do something
> deferred = someFunctionThatReturnsADeferred()
> deferred.addCallback(State3)
>
> def State3(someData):
> # do something
> if someData == 'State4':
> deferred = someFunctionThatReturnsADeferred()
> func = State4
> elif someData == 'State5':
> deferred = someOtherFunctionThatReturnsADeferred()
> func = State5
> ...
> deferred.addCallback(func)
>
> if __name__ = "__main__":
> initialize()
> reactor.run()
>
> As for the Twisted loop. Well, you don't really see the Twisted loop
> since that is hidden in the reactor. Also you should distinguish
> between writing a new protocol and using an existing one.
>
> In the case of XMLRPC, creating the server isn't the problem.
>
> http://twistedmatrix.com/projects/web/documentation/howto/xmlrpc.html
>
> Once a XMLRPC server is created, Twisted will take responsibility for
> creating new instances (or threads if you want to see it that way). If
> you still need a state machine, then the only hiccup I can see is
> sharing state machine (if you really need one) between XMLRPC method
> invocations.
>
> Cheers,
> Andrew
>
[Doug Farrell] Thank you very much for your detailed response, I'm kinda
getting it and am going to try out a prototype to make sure I do. As you
mention, Twisted does take care of a lot of the issues dealing with
concurrency. Having written a few threaded applications, I didn't really
want to get into starting my state machine in a thread and then having
to deal with all the cross thread data safety issues.
One thing I'm still a little confused by in your reply is how you're
getting the deferred instance. Is there a particular reason your example
does this:
deferred = someOtherFunctionThatReturnsADeferred()
rather than this:
deferred = defer.deferred()
I just want to understand if there a reason the deferred is being
created in the other function.
Again, thanks for your help and response!
Doug
More information about the Twisted-Python
mailing list