@treeform thanks for your reply! I've tried the pg, but I can't wrap my head around using it for my case. My case is just running a pg client (forever), subscribe (listen) to a channel named "testChannel", and echo every notification payload sent through the channel. I think something simple as,
let res = waitFor pgcon.row(sql"LISTEN \""testChannel\""", @[])
doesn't do the work.
Would you mind help out?
i've done it like this, i was not able to get the notice receiver or the notice processor callback to work, but polling worked for my use case to i tried not so hard.
import db_postgres
import postgres
let db = open("<server>", "<user>", "<password>", "<db>")
import os
db.exec(sql("LISTEN foo;"))
var idx = 0
while true:
idx.inc
echo "TICK"
echo (db.PPGconn).pqconsumeInput()
while true:
echo "in:", (db.PPGconn).pqconsumeInput()
let noti = (db.PPGconn).pqnotifies()
if noti.isNil: break
echo repr noti
sleep(10000)
@enthus1ast thanks for the reply! I tried hard to read documentation on nim asyncdispatch and related documentation on postgresql, and come up with the following solution, it did work, but I'm not a experienced dev on system programming, I really need you help to review it:
import db_postgres
import postgres
let pgcon = open("<server>", "<user>", "<password>", "<db>")
pgcon.exec(sql """listen "testChannel" """)
proc recvNotify(): Future[cstring] =
var retFuture = newFuture[cstring]()
let sock = AsyncFD(pqsocket(pgcon))
proc cb(fd: AsyncFD): bool {.closure, gcsafe.} =
if not retFuture.finished:
if pqconsumeInput(pgcon)==0:
retFuture.fail(newException(ValueError, $pqerrorMessage(pgcon)))
else:
var notify = pqnotifies(pgcon)
if notify != nil:
retFuture.complete(notify.extra)
unregister(sock)
return true
register(sock)
addRead(sock, cb)
return retFuture
proc main() {.async.} =
while true:
var msg = await recvNotify()
echo msg
asyncCheck main()
runForever()
Here is the code example 33.2 on https://www.postgresql.org/docs/current/libpq-notify.html