Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Cameron Simpson Newsgroups: comp.lang.python Subject: Re: Bi-directional sub-process communication Date: Wed, 25 Nov 2015 09:07:22 +1100 Lines: 62 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed X-Trace: news.uni-berlin.de attaevN9tCT/EwmhFcTdUAPc3xN+ny1pMVg+ZE6o8PZQ== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'handler': 0.04; 'jeff': 0.04; 'caller': 0.07; 'raises': 0.07; 'subject:skip:c 10': 0.07; 'cc:addr:python-list': 0.09; 'attribute.': 0.09; 'methods,': 0.09; 'raised.': 0.09; 'subclasses': 0.09; 'subject:process': 0.09; 'thread': 0.10; '23,': 0.16; '>on': 0.16; 'allocates': 0.16; 'callable,': 0.16; 'cc:name:python': 0.16; 'collects': 0.16; 'deferred': 0.16; 'fires': 0.16; 'from:addr:cs': 0.16; 'from:addr:zip.com.au': 0.16; 'from:name:cameron simpson': 0.16; 'llama': 0.16; 'message-id:@cskk.homeip.net': 0.16; 'obviously,': 0.16; 'received:211.29': 0.16; 'received:211.29.132': 0.16; 'received:cskk.homeip.net': 0.16; 'received:homeip.net': 0.16; 'received:io': 0.16; 'received:optusnet.com.au': 0.16; 'received:psf.io': 0.16; 'received:syd.optusnet.com.au': 0.16; 'run.': 0.16; 'simpson': 0.16; 'subject:sub': 0.16; 'subprocess,': 0.16; 'suite.': 0.16; 'wait.': 0.16; 'wrote:': 0.16; 'later': 0.16; 'attribute': 0.18; 'result,': 0.18; ';-)': 0.18; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; '(by': 0.22; 'class,': 0.22; 'cheers,': 0.22; 'ride': 0.23; 'sets': 0.23; 'this:': 0.23; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; 'module': 0.25; "i've": 0.25; 'header:User-Agent:1': 0.26; 'function': 0.28; 'blocking': 0.29; 'etc).': 0.29; 'information;': 0.29; 'queue': 0.29; 'class.': 0.30; 'core': 0.32; 'returned': 0.32; 'run': 0.33; 'class': 0.33; 'common': 0.33; 'lets': 0.33; 'received:com.au': 0.33; 'gets': 0.35; 'instance': 0.35; 'nov': 0.35; 'something': 0.35; 'submitting': 0.35; 'supports': 0.35; 'but': 0.36; 'data.': 0.36; 'event.': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'method': 0.37; 'charset:us-ascii': 0.37; 'things': 0.38; 'stuff': 0.38; 'does': 0.39; "didn't": 0.39; 'subject:-': 0.39; 'called': 0.40; 'some': 0.40; 'easy': 0.60; 'waiting': 0.60; 'your': 0.60; 'default': 0.61; 'more': 0.63; 'cameron': 0.66; 'future.': 0.67; 'receive': 0.71; 'sounds': 0.76; 'completion': 0.79; '**kw)': 0.84; 'dispatched': 0.84; 'or:': 0.84; 'slot,': 0.84; 'wakes': 0.84; 'alone.': 0.91; 'cooperation': 0.97 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=R4L+YolX c=1 sm=1 tr=0 a=EBcx3FSHdMIVXc4TnVAPjw==:117 a=EBcx3FSHdMIVXc4TnVAPjw==:17 a=ZtCCktOnAAAA:8 a=PO7r1zJSAAAA:8 a=vrnE16BAAAAA:8 a=kj9zAlcOel0A:10 a=qtqOOiqGOCEA:10 a=pGLkceISAAAA:8 a=0thQQEepAAAA:8 a=c_FIwp6yZ0jer71h2D8A:9 a=CjuIK1q_8ugA:10 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:99403 On 24Nov2015 14:53, Ian Kelly wrote: >On Mon, Nov 23, 2015 at 10:25 PM, Cameron Simpson 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 Ride with a llama and you never ride alone. - Jeff Earls, DoD #0530,