Hi Doug: >Message: 1 >Date: Thu, 26 Mar 2009 14:26:17 -0400 >From: "Doug Farrell" <dfarr...@mypublisher.com> >Subject: [Twisted-Python] how to create state machines? >To: <twisted-python@twistedmatrix.com> >Message-ID: <318f79422adc5041a93343721f84474d01a8b...@exchange.mypublisher.local> >Content-Type: text/plain; charset="us-ascii"
>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 _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python