Skip to content

Commit 04f58ea

Browse files
committed
Add handler for LISTEN/NOTIFY notifications
lib/pq currently has a dedicated set of functionality for subscribing to LISTEN/NOTIFY messages, but you have to use it on a separate connection. This commit adds a simple way to register a handler for notifications that is on an ordinary database connection. This is useful if a user wants to LISTEN to a channel on the same connection as their ordinary database connection.
1 parent 1172019 commit 04f58ea

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

conn.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ type conn struct {
152152

153153
// If not nil, notices will be synchronously sent here
154154
noticeHandler func(*Error)
155+
156+
// If not nil, notifications will be synchronously sent here
157+
notificationHandler func(*Notification)
155158
}
156159

157160
// Handle driver-side settings in parsed connection string.
@@ -977,6 +980,10 @@ func (cn *conn) recv() (t byte, r *readBuf) {
977980
if n := cn.noticeHandler; n != nil {
978981
n(parseError(r))
979982
}
983+
case 'A':
984+
if n := cn.notificationHandler; n != nil {
985+
n(recvNotification(r))
986+
}
980987
default:
981988
return
982989
}
@@ -994,7 +1001,9 @@ func (cn *conn) recv1Buf(r *readBuf) byte {
9941001

9951002
switch t {
9961003
case 'A':
997-
// ignore
1004+
if n := cn.notificationHandler; n != nil {
1005+
n(recvNotification(r))
1006+
}
9981007
case 'N':
9991008
if n := cn.noticeHandler; n != nil {
10001009
n(parseError(r))

notify.go

+11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package pq
44
// This module contains support for Postgres LISTEN/NOTIFY.
55

66
import (
7+
"database/sql/driver"
78
"errors"
89
"fmt"
910
"sync"
@@ -29,6 +30,16 @@ func recvNotification(r *readBuf) *Notification {
2930
return &Notification{bePid, channel, extra}
3031
}
3132

33+
// SetNotificationHandler sets the given notification handler on the given
34+
// connection. A runtime panic occurs if c is not a pq connection. A nil handler
35+
// may be used to unset it.
36+
//
37+
// Note: Notification handlers are executed synchronously by pq meaning commands
38+
// won't continue to be processed until the handler returns.
39+
func SetNotificationHandler(c driver.Conn, handler func(*Notification)) {
40+
c.(*conn).notificationHandler = handler
41+
}
42+
3243
const (
3344
connStateIdle int32 = iota
3445
connStateExpectResponse

0 commit comments

Comments
 (0)