Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Unable to cancel query 2.4.5-1 (debian stable)

#221

Submitted by: TimRex

I seem to have a problem running psycopg2 version 2.4.5-1 (debian stable) against Python 3 v3.2.3-6

I'm unable to signal any python process that is currently executing a query, it simply ignores the signal until the query has completed (in some cases, these can be very long queries).

In production, this is less of an issue we won't really be wanting to kill any processes as a matter of habit (and we can always -9 them). - but when developing, it really gets in the way.. A simple ctrl-c just won't cut it.

Is this fixed in more recent versions? Convincing our draconian admins to allow non-stable packages on their precious boxes ought to be fun.

Cheers!

Reported by Psycopg website · June 30th, 2014 @ 05:07 PM

State: invalid
Milestone: none
Assigned to: nobody

Activity

  1. Daniele Varrazzo
    Daniele Varrazzo

    Hello,

    yes, I know the issue. No, it's not fixed in the master and I don't know how to fix it; actually I don't think it's generally fixable in psycopg: you may have two thread running a query: should ctrl-c cancel all of them? What to do is obvious only when there is a single connection and a single thread but psycopg can run several query at once, each in a different thread.

    You may try to run a parallel thread detecting the ctrl-c and cancelling the query you want using connection.cancel() on the connection you want, but you should check how python threads and signal interact.

    Note that a way to cancel the query that is more gentle than a kill -9 is to pg_cancel_backend the backend pid of the connection: psycopg will break with an exception.

    I'm leaving the issue here as a memo: it won't be fixed in psycopg but we may try and write a recipe to add to the docs to show how to deal with the issue.

    June 30th, 2014 @ 09:28 PM

  2. Daniele Varrazzo
    Daniele Varrazzo
    • State changed from new to invalid

    A way to make the query interruptable is to work in green mode with a wait callback that can tolerate being broken by ctrl-c:

    from select import select
    from psycopg2.extensions import POLL_OK, POLL_READ, POLL_WRITE
    
    def wait_select_inter(conn):
        while 1:
            try:
                state = conn.poll()
                if state == POLL_OK:
                    break
                elif state == POLL_READ:
                    select([conn.fileno()], [], [])
                elif state == POLL_WRITE:
                    select([], [conn.fileno()], [])
                else:
                    raise conn.OperationalError("bad state from poll: %s" % state)
            except KeyboardInterrupt:
                conn.cancel()
                # the loop will be broken by a server error
                continue
    
    psycopg2.extensions.set_wait_callback(wait_select_inter)
    

    An interactive session would look like:

    >>> cnn = psycopg2.connect('')
    >>> cur = cnn.cursor()
    >>> cur.execute("select pg_sleep(10)")
    ^C
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    QueryCanceledError: canceling statement due to user request
    
    >>> cnn.rollback() # connection is in error now
    # the connection can be reused now
    

    I'm closing the bug as it won't be fixed in the lib but will try to make this recipe to float around.

    July 20th, 2014 @ 10:38 AM