Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #102707
| From | "Frank Millman" <frank@chagford.com> |
|---|---|
| Newsgroups | comp.lang.python |
| Subject | asyncio and blocking - an update |
| Date | 2016-02-09 09:33 +0200 |
| Message-ID | <mailman.0.1455003248.29838.python-list@python.org> (permalink) |
Hi all Some of you may have been following my attempts to modify my asyncio app so that it does not block when accessing the database. Here is an update. I came up with what felt like a good idea. Run the database handler in a separate thread, pass requests to it using a queue.Queue, and get it to pass results back using an asyncio.Queue. It works, but I had a vague sense that performance was a bit sluggish, so I tried the 'recommended' approach of using asyncio.run_in_executor() to execute database calls in a separate thread. It felt a bit faster. Now I have written a proper timing test, and the recommended approach is much faster. I am not 100% sure of the reason, but I think the problem is that, with my method, when the database tries to 'put' a row on the return queue, it has to use 'loop.call_soon_threadsafe()', and this seems to create a bottleneck. It would not matter so much if I used cur.fetchall(), and sent all the rows back in one 'put', but I really wanted to iterate over the cursor and 'put' a row at a time. The idea was that it would be truly asynchronous from end to end - the database handler would retrieve rows one at a time, and via the queue my app would process them one at a time, all without blocking. I can switch to fetchall(), but then there is no benefit over the recommended approach. Although fetchall() is non-blocking, once the rows are received as a list the function that processes them effectively does block. If that became a problem one could use an Asynchronous Iterator to process the list, but I have not had that need yet. Writing timing tests is tricky. It is possible that under some circumstances, with a heavy load, a large table, and a time-consuming function to process each row, the overhead of call_soon_threadsafe() would be minimised and my approach might be effective. For now, however, I will regretfully abandon my approach and stick with run_in_executor(). Frank Millman
Back to comp.lang.python | Previous | Next | Find similar | Unroll thread
asyncio and blocking - an update "Frank Millman" <frank@chagford.com> - 2016-02-09 09:33 +0200
csiph-web