NOTIFYs fix and poll status changes

POLL_OK has been changed from 3 to 0 to let the user specify a short loop
just as "if not curs.poll()" instead of having to check for write and read
separately. For an example of this, see examples/notify.py.
This commit is contained in:
Federico Di Gregorio 2010-04-05 16:52:25 +02:00
parent e15bc9da05
commit c1a24f4ca2
7 changed files with 25 additions and 18 deletions

View File

@ -1,3 +1,9 @@
2010-04-05 Federico Di Gregorio <fog@initd.org>
* Fixed problem with asynchronous NOTIFYs.
* Integrated async pacthes from Jan's git tree.
2010-03-13 Federico Di Gregorio <fog@initd.org>
* Release 2.0.14.

View File

@ -39,5 +39,5 @@ while 1:
if select.select([curs],[],[],5)==([],[],[]):
print "Timeout"
else:
if curs.isready():
if not curs.poll():
print "Got NOTIFY: %s" % str(curs.connection.notifies.pop())

View File

@ -76,10 +76,10 @@ STATUS_ASYNC = 4
# This is a usefull mnemonic to check if the connection is in a transaction
STATUS_IN_TRANSACTION = STATUS_BEGIN
"""psycopg async connection polling values"""
"""psycopg asynchronous connection polling values"""
POLL_OK = 0
POLL_READ = 1
POLL_WRITE = 2
POLL_OK = 3
"""Backend transaction status values."""
TRANSACTION_STATUS_IDLE = 0

View File

@ -53,11 +53,10 @@ extern "C" {
#define ASYNC_READ 1
#define ASYNC_WRITE 2
/* polling result, try to keep in sync with PostgresPollingStatusType from
libpq-fe.h */
/* polling result */
#define PSYCO_POLL_OK 0
#define PSYCO_POLL_READ 1
#define PSYCO_POLL_WRITE 2
#define PSYCO_POLL_OK 3
/* Hard limit on the notices stored by the Python connection */
#define CONN_NOTICES_LIMIT 50

View File

@ -62,10 +62,10 @@ typedef struct {
PyObject *pgstatus; /* last message from the server after an execute */
Oid lastoid; /* last oid from an insert or InvalidOid */
PyObject *casts; /* an array (tuple) of typecast functions */
PyObject *caster; /* the current typecaster object */
PyObject *casts; /* an array (tuple) of typecast functions */
PyObject *caster; /* the current typecaster object */
PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */
#define DEFAULT_COPYSIZE 16384
#define DEFAULT_COPYBUFF 8132

View File

@ -141,9 +141,16 @@ curs_poll_fetch(cursorObject *self)
return PyInt_FromLong(PSYCO_POLL_READ);
}
/* data has arrived, try to fetch all of it or, if it failed, tell the
user to wait more */
last_result = curs_get_last_result(self);
/* try to fetch the data only if this was a poll following a read
request; else just return POLL_OK to the user: this is necessary
because of asynchronous NOTIFYs that can be sent by the backend
even if the user didn't asked for them */
if (self->conn->async_status == ASYNC_READ)
last_result = curs_get_last_result(self);
else
last_result = 0;
if (last_result == 0) {
Dprintf("cur_poll_fetch: returning %d", PSYCO_POLL_OK);
return PyInt_FromLong(PSYCO_POLL_OK);

View File

@ -1485,14 +1485,9 @@ psyco_curs_poll(cursorObject *self)
if (self->conn->async_status == ASYNC_WRITE) {
return curs_poll_send(self);
}
else if (self->conn->async_status == ASYNC_READ) {
else {
return curs_poll_fetch(self);
}
else {
PyErr_Format(OperationalError, "unexpected execution status: %d",
self->conn->async_status);
return NULL;
}
}
/* extension: closed - return true if cursor is closed*/