Re: NOTIFY in asynchronous mode
От | Jan Urbański |
---|---|
Тема | Re: NOTIFY in asynchronous mode |
Дата | |
Msg-id | 4EB52352.2040802@wulczer.org обсуждение исходный текст |
Ответ на | NOTIFY in asynchronous mode (Tobias Oberstein <tobias.oberstein@tavendo.de>) |
Ответы |
Re: NOTIFY in asynchronous mode
(Tobias Oberstein <tobias.oberstein@tavendo.de>)
|
Список | psycopg |
On 05/11/11 11:54, Tobias Oberstein wrote: > -- Original message ----- >>> What would be provided to the callback? >>> >>> Channel (from NOTIFIY), Payload (from NOTIFIY), Connection (txpostgres) >> ? >> >> Probably simply the psycopg2 Notify object. > > Ok, fine also. > > And not the Connection object on which it was received? Ok, maybe it's > not needed: When I want to do some db stuff within the callback, should > not make a difference on what connection I do that. You would register the callback on the Connection object, so you could tell it which connection it will get registered on beforehand. > Few other design Qs: > > Is it possible to UNLISTEN? Sure, because you'd call both LISTEN and UNLISTEN as SQL statements with runQuery. > Or unregister a callback on a channel? Or set it to None? > > Are callbacks for channels registered "globally" or per connection? The callbacks would be registered per connection, since it's the connection who receives notifications. > Can there be only one callback at most registered per channel? Channel handling would be entirely up to the client. Here's a quick example of how it could work (based on the patch I previously mentioned from Jan Pobrislo, with a slightly changed callback API): from twisted.python import log from twisted.python.util import println class NotifyObserver(object): def __init__(self, conn): self.conn = conn def __call__(self, notify): if notify.channel == 'channel1': println('got notify on channel 1, unlistening and removing') self.conn.removeNotifyObserver(self) d = conn.runQuery('UNLISTEN *') d.addCallback(lambda _: println('unlistened')) d.addErrback(log.err) else: println('got some other notify') # conn is a txpostgres Connection observer = NotifyObserver(conn) # any number of different callables can be registered, here we just register one conn.addNotifyObserver(observer) d = conn.runQuery('LISTEN channel1') d.addCallback(lambda _: conn.runQuery('LISTEN channel2')) d.addCallback(lanbda _: println('listening') # then, after the program prints "listening" execute from psql in another session =$ NOTIFY channel2; =$ NOTIFY channel2; =$ NOTIFY channel1; =$ NOTIFY channel2; # which would yield the following from the running program "got some other notify" "got some other notify" "got notify on channel 1, unlistening and removing" # note that after a notify on channel1 is received, the observer is gone and no more notifies are processed I think that's a reasonably simple API and one that allows you to do anything you want without introducing some extra interfaces that notify observers have to implement, just requiring that they are callable. Cheers, Jan
В списке psycopg по дате отправления: