Bi-directional sub-process communication

Cameron Simpson cs at zip.com.au
Tue Nov 24 17:07:22 EST 2015


On 24Nov2015 14:53, Ian Kelly <ian.g.kelly at gmail.com> wrote:
>On Mon, Nov 23, 2015 at 10:25 PM, Cameron Simpson <cs at zip.com.au> wrote:
>> Then #3. I would have a common function/method for submitting a request to
>> go to the subprocess, and have that method return an Event on which to wait.
>> Then caller then just waits for the Event and collects the data. Obviously,
>> the method does not just return the Event, but an Event and something to
>> receive the return data. I've got a class called a Result for this kind of
>> thing; make a small class containing an Event and which will have a .result
>> attribute for the return information; the submitting method allocates one of
>> these and returns it. The response handler gets the instance (by looking it
>> up from the tag), sets the .result attribute and fires the Event. Your
>> caller wakes up from waiting on the Event and consults the .result
>> attribute.
>
>Your Result sounds suspiciously like a Future. ;-)

Yeah. I already had this stuff when the futures module was released, with some 
additional stuff futures didn't have (eg my dispatch queue is a priority queue, 
which is handy for some kinds of workflows; default dispatch is FIFO).

My commonest use case/instance is a LateFunction, returned from my Later class.  
Use:

  L = Later()
  LF = L.defer(cllable, *a, *kw)
  ...
  result = LF()

When you call a LateFunction you get the function result, blocking if it has 
not yet been run. It also raises if the deferred function raised. It has 
additional methods, but that is the core use: make it look like a function.

You can do other easy things like:

  L.after(LFs, callable, *a, **kw)

to have a function dispatched after the completion of other LateFunctions or:

  with L.ready():
    ... suite ...

to block until the Later has a slot, then run the suite.

My Result and LateFunctions are subclasses of an Asynchron base class, which 
lets you wait for the result to arrive and has the common methods (wait, etc).  
The Result class supports this:

  R = Result()

  # caller, blocks until value received
  value = R.result

  # worker: deliver result
  R.result = func(blah)

This makes thread cooperation far far more friendly.

Cheers,
Cameron Simpson <cs at zip.com.au>

Ride with a llama and you never ride alone.
- Jeff Earls, DoD #0530, <jearls at tekig6.pen.tek.com>



More information about the Python-list mailing list