Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: "Frank Millman" Newsgroups: comp.lang.python Subject: Re: asyncio - how to stop background task cleanly Date: Sun, 7 Feb 2016 09:10:36 +0200 Lines: 78 Message-ID: References: <87lh6ys052.fsf@elektro.pacujo.net> <87fux5svhk.fsf@elektro.pacujo.net> <8737t5shhp.fsf@elektro.pacujo.net> Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=response Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de sWiKOXna6QHpD0aA5L1KNwLW2zI8FJjJZ1POuNM1VrDw== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.010 X-Spam-Evidence: '*H*': 0.98; '*S*': 0.00; 'startup': 0.05; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'def': 0.13; 'async': 0.16; 'hangs.': 0.16; 'received:80.91.229.3': 0.16; 'received:io': 0.16; 'received:plane.gmane.org': 0.16; 'received:psf.io': 0.16; 'seconds,': 0.16; 'simulate': 0.16; 'stage.': 0.16; 'subject:stop': 0.16; 't.join()': 0.16; 'task.': 0.16; 'threading': 0.16; 'true:': 0.16; 'try:': 0.18; 'delay': 0.22; 'wrote': 0.23; 'specially': 0.23; 'thanks,': 0.24; 'tried': 0.24; 'words': 0.24; 'header:In-Reply-To:1': 0.24; 'module': 0.25; 'appear': 0.26; 'header:X-Complaints-To:1': 0.26; 'skip:_ 20': 0.26; 'supported': 0.27; 'cancel': 0.27; 'executing': 0.27; "skip:' 10": 0.28; 'task': 0.30; 'anyone': 0.32; 'url:python': 0.33; 'traceback': 0.33; 'except': 0.34; 'but': 0.36; 'too': 0.36; 'should': 0.36; 'needed': 0.36; 'there': 0.36; 'url:org': 0.36; 'url:library': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'thanks': 0.37; 'received:org': 0.37; 'busy': 0.38; 'skip:e 20': 0.39; 'to:addr:python.org': 0.40; 'url:3': 0.60; 'waiting': 0.60; 'press': 0.61; 'skip:a 40': 0.64; 'here': 0.66; 'frank': 0.72; 'skip:n 40': 0.72; 'soon.': 0.73; 'await': 0.76; 'actually,': 0.84; 'appear,': 0.84; 'cancelled': 0.91; 'do:': 0.91; 'spoke': 0.91 X-Injected-Via-Gmane: http://gmane.org/ X-Gmane-NNTP-Posting-Host: 197.89.92.138 In-Reply-To: X-MSMail-Priority: Normal Importance: Normal X-Newsreader: Microsoft Windows Live Mail 15.4.3502.922 X-MimeOLE: Produced By Microsoft MimeOLE V15.4.3502.922 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:102612 "Frank Millman" wrote in message news:n96kjr$mvl$1@ger.gmane.org... > > "Marko Rauhamaa" wrote in message > news:8737t5shhp.fsf@elektro.pacujo.net... > > > Actually, cancellation is specially supported in asyncio ( > https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.cancel>) > > so this should do: > > > > async def background_task(): > > while True: > > await perform_task() > > await asyncio.sleep(10) > > > > That's exactly what I needed - thanks, Marko > > async def background_task() > try: > while True: > await perform_task() > await asyncio.sleep(10) > except asyncio.CancelledError: > await perform_cleanup() > > At startup - > > task = asyncio.ensure_future(background_task()) > > At shutdown - > > task.cancel() > await asyncio.wait([task]) > > Works perfectly - thanks again. > Alas, I spoke too soon. I tried to simulate what would happen if the background task was busy with a task when it was cancelled - async def background_task() try: while True: print('start') time.sleep(2) print('done') await asyncio.sleep(10) except asyncio.CancelledError: print('cleanup') print('DONE') If I cancel after a pair of 'start/done' appear, the background task is in the 'asyncio.sleep' stage. The words 'cleanup' and 'DONE' appear instantly, and the program halts. If I cancel after 'start', but before 'done', the background task is executing a task. There is a delay of up to 2 seconds, then the words 'done', 'cleanup', and 'DONE' appear, but the program hangs. If I press Ctrl+C, I get a traceback from the threading module - line 1288, in _shutdown t.join() line 1054, in join self._wait_for_tstate_lock() line 1070, in _wait_for_tstate_lock KeyboardInterrupt So it is waiting for join() to complete. I will continue investigating, but will report it here to see if anyone can come up with an explanation/solution. Thanks Frank