Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: "Frank Millman" Newsgroups: comp.lang.python Subject: Re: Question about asyncio and blocking operations Date: Thu, 28 Jan 2016 18:40:56 +0200 Lines: 65 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de BuD7POo4WSkuzrIe4QB5oQ2SsHmSCXuzkXVfM62ujPvA== 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; 'yet.': 0.03; 'handler': 0.04; 'none:': 0.05; 'subject:Question': 0.05; 'caller': 0.07; 'works.': 0.07; 'covered.': 0.09; 'empty,': 0.09; 'pause': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'rows': 0.09; 'bug': 0.10; 'assume': 0.11; 'jan': 0.11; '2016': 0.16; 'called,': 0.16; 'queuing': 0.16; 'received:80.91.229.3': 0.16; 'received:io': 0.16; 'received:plane.gmane.org': 0.16; 'received:psf.io': 0.16; 'row': 0.16; 'row)': 0.16; 'sequential': 0.16; 'skip:n 70': 0.16; 'true:': 0.16; 'wrote:': 0.16; 'creates': 0.18; 'variable': 0.18; 'delay': 0.22; 'am,': 0.23; 'seems': 0.23; 'wrote': 0.23; 'header:In-Reply-To:1': 0.24; 'requests': 0.25; 'appear': 0.26; 'header:X-Complaints-To:1': 0.26; 'back.': 0.27; 'this.': 0.28; "skip:' 10": 0.28; 'necessary,': 0.29; 'prints': 0.29; 'queue': 0.29; 'request,': 0.29; 'sleep': 0.29; 'code': 0.30; 'task': 0.30; 'seconds': 0.31; 'supposed': 0.31; 'post': 0.31; 'noticed': 0.32; 'problem': 0.33; 'this?': 0.34; 'running': 0.34; 'could': 0.35; 'confirmed': 0.35; 'instance': 0.35; 'something': 0.35; 'but': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'there,': 0.37; 'received:org': 0.37; 'thought': 0.37; 'anything': 0.38; 'data': 0.39; 'sure': 0.39; 'enough': 0.39; 'easily': 0.39; 'to:addr:python.org': 0.40; 'some': 0.40; 'waiting': 0.60; 'increased': 0.61; 'back': 0.62; 'more': 0.63; 'request.': 0.66; 'virtually': 0.66; 'here': 0.66; 'future.': 0.67; 'frank': 0.72; 'await': 0.76; 'instantly.': 0.91 X-Injected-Via-Gmane: http://gmane.org/ X-Gmane-NNTP-Posting-Host: 197.89.251.254 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.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:102192 "Ian Kelly" wrote in message news:CALwzidnGbz7kM=D7MKua2tA9-csFn9u0OHL0w-X5Bbixpcw4Ow@mail.gmail.com... > On Jan 28, 2016 4:13 AM, "Frank Millman" wrote: > > > > I *think* I have this one covered. When the caller makes a request, it > creates an instance of an asyncio.Queue, and includes it with the request. > The db handler uses this queue to send the result back. > > > > Do you see any problem with this? > > That seems reasonable to me. I assume that when you send the result back > you would be queuing up individual rows and not just sending a single > object across, which could be more easily with just a single future. > I have hit a snag. It feels like a bug in 'await q.get()', though I am sure it is just me misunderstanding how it works. I can post some working code if necessary, but here is a short description. Here is the database handler - 'request_queue' is a queue.Queue - while not request_queue.empty(): return_queue, sql = request_queue.get() cur.execute(sql) for row in cur: return_queue.put_nowait(row) return_queue.put_nowait(None) request_queue.task_done() The caller requests some data from the database like this. return_queue = asyncio.Queue() sql = 'SELECT ...' request_queue.put((return_queue, sql)) while True: row = await return_queue.get() if row is None: break print('got', row) return_queue.task_done() The first time 'await return_queue.get()' is called, return_queue is empty, as the db handler has not had time to do anything yet. It is supposed to pause there, wait for something to appear in the queue, and then process it. I have confirmed that the db handler populates the queue virtually instantly. What seems to happen is that it pauses there, but then waits for some other event in the event loop to occur before it continues. Then it processes all rows very quickly. I am running a 'counter' task in the background that prints a sequential number, using await asyncio.sleep(1). I noticed a short but variable delay before the rows were printed, and thought it might be waiting for the counter. I increased the sleep to 10, and sure enough it now waits up to 10 seconds before printing any rows. Any ideas? Frank