-
Notifications
You must be signed in to change notification settings - Fork 20
Description
The attached patch provides the asynchronous operations described in section 31.4 of the PostgreSQL manual. I believe everything described in that section is available with these exceptions:
- there's no prepared statement support
- I didn't implement
PQsetSingleRowMode(). This would require a possibly small change to the way that query results are retrieved that I thought would go better as a separate change set - I didn't implement
PQconsumeInput()orPQisBusy(). I don't really understand the point of these functions, they seem to have marginal utility outside notification reception, and I wasn't sure exactly how to document them. It might make sense to have an isbusy() call which calls both, but I don't really know if that fits anybody's use case - I seem to have left out
PQflush(). This is an oversight. In general, the non-blocking operations are not well tested.
In general, the changes allow the database to be used in an event-driven application, and for other applications, there are some parallelism benefits:
- Connections can be completed in the background, which can speed up use cases where for instance the application needs to connect to several databases at once
- when multiple semi-colon-delimited queries are run in a single call, the results to all the queries are returned
- the application can do other work while waiting for queries to complete
- copy and large object operations can use non-blocking IO
Query operations work essentially the same way as they do now, except all the result codes are no returned by getresult(), dictresult() or namedresult(), cases where query() returns None, getresult() et al return '', and you have to call getresult() et al until they return None. Also, exceptions raised by bad queries are raised by getresult() et al, not by the query function.
The result member of pgqueryobject is changed by each call to getresult() et al, so you can't get the same query result twice when using asynchronous calls, and functions which depend on the result member don't work until after a call to getresult() et al.
Because of this last point, I had to reorganize _namedresult(). That's the only Python change other than the unit test.
C code changes are:
- some new functions
- change to
connect()to take a new argument and callPQconnectStartParams()when appropriate - added code to
getresult()anddictresult()to callPQgetResult()when appropriate. Looking at it now, this block of code has got to be quite big and maybe should move to its own function - renamed
pg_queryto_pg_queryand added a new argument. This is called from wrapper functionspg_query()andpg_sendquery() - moved scalar result processing from
pg_query()to a new function,_check_result_status() - changed
pg_query()to callPQsendQuery()orPQsendQueryParams()when appropriate
Attachments:
- pygresql-async-1.txt (Docs and Python)
- pygresql-async-2.txt (C Module)
- asynctests.patch.txt (Newer Patch)
- asynctests.patch.txt (Tests)
(contributed by Patrick TJ !McPhee via mailing list, 2015-08-03, copied from Trac ticket 49)