[Twisted-Python] Tie two event loops

Hi all, I'm new to twisted but am having trouble getting my head around how to structure my application with this new approach. I'm creating a server that accepts client connections and then drives the client according to a simple, line-oriented protocol. The server sends the request (1 line), and receives a single lined result. I'd like the server to offer an API to generate the correct request lines to the client, and return the results (either blocking or asynchronously). So in effect, I have two event loops, one from the Network and one from whatever's sending the API requests (command line?). Can anyone offer any guidance on how to tie these two parts together? My instinct is to have the two event loops in separate threads and communicate through Queue.Queue, but that doesn't seem to follow the spirit of twisted. And I guess I'd have to somehow tell the reactor to poll the Queue object for requests, and then dispatch it to the relevant method to send out to the client. I've looked at threadedselectreactor but can't seem to find any decent documentation to even decide if it's write for what I want. Any advice would be much appreciated. Thanks, Paul

On Wed, Jul 2, 2008 at 9:46 AM, Paul Wilson <paulalexwilson@gmail.com> wrote:
Hi all,
I'm new to twisted but am having trouble getting my head around how to structure my application with this new approach.
I'm creating a server that accepts client connections and then drives the client according to a simple, line-oriented protocol. The server sends the request (1 line), and receives a single lined result. I'd like the server to offer an API to generate the correct request lines to the client, and return the results (either blocking or asynchronously). So in effect, I have two event loops, one from the Network and one from whatever's sending the API requests (command line?).
Can anyone offer any guidance on how to tie these two parts together? My instinct is to have the two event loops in separate threads and communicate through Queue.Queue, but that doesn't seem to follow the spirit of twisted. And I guess I'd have to somehow tell the reactor to poll the Queue object for requests, and then dispatch it to the relevant method to send out to the client. I've looked at threadedselectreactor but can't seem to find any decent documentation to even decide if it's write for what I want.
Any advice would be much appreciated.
Thanks, Paul
If I understand your problem correctly (and I'm not sure that I do, so keep that in mind), then what you probably want is something like a Twisted app using two Protocol objects (perhaps in two different "services"), one to talk to your clients, and one to talk to your API-generator-thingy (command line). Then you just need a way for these to communicate...someplace to store the state. A Queue.Queue is probably a good choice, but I'm not entirely sure where you would put it. Try looking around for examples that have multiple services and see how they share state. I think the Twisted book might have something useful in this regard, though I don't have it with me ATM. Perhaps wiser heads than mine will have better ideas/comments. Kevin Horn

On Wed, 2 Jul 2008 15:46:05 +0100, Paul Wilson <paulalexwilson@gmail.com> wrote:
Hi all,
I'm new to twisted but am having trouble getting my head around how to structure my application with this new approach.
I'm creating a server that accepts client connections and then drives the client according to a simple, line-oriented protocol. The server sends the request (1 line), and receives a single lined result. I'd like the server to offer an API to generate the correct request lines to the client, and return the results (either blocking or asynchronously). So in effect, I have two event loops, one from the Network and one from whatever's sending the API requests (command line?).
Can anyone offer any guidance on how to tie these two parts together? My instinct is to have the two event loops in separate threads and communicate through Queue.Queue, but that doesn't seem to follow the spirit of twisted. And I guess I'd have to somehow tell the reactor to poll the Queue object for requests, and then dispatch it to the relevant method to send out to the client. I've looked at threadedselectreactor but can't seem to find any decent documentation to even decide if it's write for what I want.
Any advice would be much appreciated.
It's not very clear what the two different event loops are for. You suggest that the synchronous API might be used by the "command line", but this doesn't necessarily require a synchronous API. It's also not clear if there is going to be a command line tool which is invoking this API via Python function calls or if it will be talking to a server that exposes some kind of network interface (since your other use case seems to involve doing this, it might save you some work to just re-use that). Another possibility is that the server process will have code running in it which wants to access this functionality but wants a synchronous API. My first suggestion is to forget about this and just use the asynchronous API everywhere. If that's too hard, then I suggest making two different APIs. This shouldn't be very hard (particularly since I think we're talking about a function that takes a string and returns another string). Then, code can just use the API that's right for it. I don't know if this response has made any sense, because I really don't feel like I understand the question. If it didn't, maybe you can try to clarify the question a bit, perhaps providing some examples (either in English or in Python). Jean-Paul

On 02:46 pm, paulalexwilson@gmail.com wrote:
I'm creating a server that accepts client connections and then drives the client according to a simple, line-oriented protocol. The server sends the request (1 line), and receives a single lined result. I'd like the server to offer an API to generate the correct request lines to the client, and return the results (either blocking or asynchronously). So in effect, I have two event loops, one from the Network and one from whatever's sending the API requests (command line?).
Can anyone offer any guidance on how to tie these two parts together?
As you are new to Twisted, I would strongly recommend ignoring the "either blocking or asynchronously" part, and simply return the results asynchronously, in a Deferred. It's *possible* to do what you want, but to really understand what's going on well enough to pull it off you need to be pretty well-versed in the event-driven programming model, as well as gnarly implementation specifics of Twisted itself. In my experience, most places that people think that they want async+sync interfaces to something, they actually just want async+convenient. Here are some ways you could get some benefits of a synchronous API without actually having one: If you are talking about generating requests from an interactive Python interpreter, you might consider using the interpreter bundled with Conch. Try invoking it with 'python -m twisted/conch/stdio'. This command line will notice when it receives a Deferred and display a result when it arrives. If you are talking about your *own* command line, consider using twisted.internet.stdio.StandardIO to get it to communicate with the main event loop. If this isn't really about command-lines but you want to write little "scripts" that have extended conversations with a client and process lots of different results, consider using the twisted.internet.defer.inlineCallbacks decorator with Python 2.5 generators. This syntactic convenience will let you avoid defining functions to handle callbacks, and will therefore shorten certain kinds of code. I hope one of those solutions helps!
participants (4)
-
glyph@divmod.com
-
Jean-Paul Calderone
-
Kevin Horn
-
Paul Wilson