Home > Enterprise >  why does the the connection cursor need to be readable for a psycopg2 notification listening loop
why does the the connection cursor need to be readable for a psycopg2 notification listening loop

Time:11-11

psycopg2 provides some example code for using postgresql notify facilities

import select
import psycopg2
import psycopg2.extensions

conn = psycopg2.connect(DSN)
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

curs = conn.cursor()
curs.execute("LISTEN test;")

print "Waiting for notifications on channel 'test'"
while True:
    if select.select([conn],[],[],5) == ([],[],[]):
        print "Timeout"
    else:
        conn.poll()
        while conn.notifies:
            notify = conn.notifies.pop(0)
            print "Got NOTIFY:", notify.pid, notify.channel, notify.payload

What is the select.select([conn],[],[],5) == ([],[],[]) code doing?

The documentation of select.select suggests that we are trying to make sure that the socket that underlies the conn is "ready for reading".

What does it mean for a psycogp2 connection to be "ready for reading"?

CodePudding user response:

conn.poll() is a nonblocking command. If there are no notifications (or other comms) available, it will still return immediately, just without having done anything. When done in a tight loop, this would be busy waiting and that is bad. It will burn an entire CPU doing nothing, and may even destabilize the whole system.

The select means "wait politely for there to be something on the connection to be read (implying poll will probably have something to do), or for 5 sec, whichever occurs first. If you instead wanted to wait indefinitely for a message to show up, just remove ,5 from the select. If you wanted to wait for something interesting to happen on the first of several handles, you would put all of them in the select list, not just conn.

  • Related