Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: "Joseph L. Casale" Newsgroups: comp.lang.python Subject: Re: Passing data across callbacks in ThreadPoolExecutor Date: Thu, 18 Feb 2016 19:06:29 +0000 Lines: 41 Message-ID: References: , Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Trace: news.uni-berlin.de 9kDntR396Vw1/lcp1bxvbAcybt9rxmU6DycVrfLu1I8A== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.004 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'source,': 0.04; 'dependency': 0.07; 'callback': 0.09; 'input,': 0.09; 'threads.': 0.09; 'thread': 0.10; 'output': 0.13; 'def': 0.13; 'result.': 0.15; 'skip:f 30': 0.15; '2016': 0.16; 'chained': 0.16; 'finishes': 0.16; 'received:172.18.0': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'succinct': 0.16; 'threads': 0.16; 'wrote:': 0.16; 'otherwise,': 0.20; 'to:2**1': 0.21; 'pass': 0.22; 'am,': 0.23; '(or': 0.23; 'seems': 0.23; 'feb': 0.23; 'thanks,': 0.24; 'header:In-Reply-To:1': 0.24; 'separate': 0.27; 'cancel': 0.27; 'specify': 0.27; 'adequate': 0.29; 'work.': 0.30; 'checks': 0.30; 'task': 0.30; 'probably': 0.31; "can't": 0.32; 'facility': 0.33; 'is?': 0.33; "i'll": 0.33; 'handle': 0.34; 'add': 0.34; 'gets': 0.35; 'execution': 0.35; 'instance': 0.35; 'tasks': 0.35; 'but': 0.36; 'there': 0.36; 'closing': 0.36; 'to:addr:python- list': 0.36; 'subject:: ': 0.37; 'detail': 0.38; 'submit': 0.39; 'skip:e 20': 0.39; 'to:addr:python.org': 0.40; 'some': 0.40; 'easy': 0.60; 'waiting': 0.60; 'your': 0.60; "you'll": 0.61; 'more': 0.63; 'subject:skip:T 10': 0.66; 'tasks.': 0.66; 'potentially': 0.67; 'increase': 0.73; 'to:name:python': 0.84; 'sitting': 0.93 X-Authority-Analysis: v=2.1 cv=WIDfJiYR c=1 sm=1 tr=0 a=g3mLq75WYuDrh3Lt0JSDww==:117 a=g3mLq75WYuDrh3Lt0JSDww==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=P90J6pEA2ccA:10 a=8nJEP1OIZ-IA:10 a=jFJIQSaiL_oA:10 a=pGLkceISAAAA:8 a=eELofTlFSX3_4V8voTAA:9 a=zt45mzrMLHIY4pwN:21 a=uWmSasGwQasM0nDk:21 a=wPNLvfGTeEIA:10 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.activenetwerx.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,RP_MATCHES_RCVD autolearn=unavailable autolearn_force=no version=3.4.0 Thread-Topic: Passing data across callbacks in ThreadPoolExecutor Thread-Index: AQHRaQOLnYiuCC9hLkqY+oiLW/4uEJ8w4q2AgAFIQtA= In-Reply-To: Accept-Language: en-CA, en-US Content-Language: en-CA X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [172.18.0.4] X-CMAE-Envelope: MS4wfKGScAdOTrWciTglr9uWyiTmLlWDxU14C12UjII7FJsCchTR1ezPQEIGzEq/958bm6SSehWD2Pfe932UyietWdQuWy1NVod4O/YHwA5MAyzObKwppZv9 XiZSXS1ksABrgX1Acw4L8ozZjCF2Bo+UgWWQS7gmYp6Zj1hOPm8lk/nvZLcUTyEKh3Z2fGGKB6urWQ== X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.21rc2 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:103144 On Thur, Feb 17, 2016 at 9:24 AM, Ian Kelly wrote: >> What is the pattern for chaining execution of tasks with ThreadPoolExecu= tor? >> Callbacks is not an adequate facility as each task I have will generate = new output. > > Can you specify in more detail what your use case is? > > If you don't mind having threads sitting around waiting, you can just > submit each chained task at the start and have each task wait on the > futures of its dependencies. The advantage of this is that it's easy > to conceptualize the dependency graph of the tasks. The disadvantage > is that it eats up extra threads. You'll probably want to increase the > size of the thread pool to handle the waiting tasks (or use a separate > ThreadPoolExecutor for each chained task). The thing with callbacks is each one gets the original tasks result. So the callback can't pass a new task result up and/or cancel the task "set". > Otherwise, is there some reason you can't use multiple callbacks, one > to handle the task's output and one to submit the chained task? >=20 > E.g.: >=20 > def chain_task2(input, f2): > f2 =3D executor.submit(task2, input, f2.result()) > f2.add_done_callback(handle_task2_done) >=20 > f1 =3D executor.submit(task1, input) > f1.add_done_callback(handle_task1_done) > f1.add_done_callback(functools.partial(chain_task2, input)) Closing over the executer instance seems potentially race'y. What happens w= hen the last task finishes and the executer checks (locking the queue) and the = task also wants to add more work. I'll check the source, but I had hoped for a more s= uccinct way. Thanks, jlc