Skip to content

Add Notifier, implemented for PostgreSQL with LISTEN/NOTIFY - #77

Merged
mattn merged 2 commits into
fiatjaf:masterfrom
mattn:feat/notifier
Sep 14, 2026
Merged

mattn merged 2 commits into
fiatjaf:masterfrom
mattn:feat/notifier

Conversation

@mattn

@mattn mattn commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Problem

A relay running as several processes on one database (e.g. behind a load balancer) has no way to push an event accepted by one process to the clients subscribed on the others: live subscriptions live in each process's memory.

fiatjaf/relayer#167 added a Notifier interface on the relayer side and resolves it on the Relay first and on the Store second. This PR adds the store side, so a backend with native change notifications can provide it out of the box.

Change

type Notifier interface {
	Notify(context.Context, *nostr.Event) error
	Notifications(context.Context) (<-chan *nostr.Event, error)
}

Optional, like Counter. The relay calls Notify for every accepted event after saving it (ephemeral ones included, since they are never saved); Notifications must deliver everything any process notified, including the caller's own, and keep the channel open until ctx is done.

PostgresBackend implements it with pg_notify / LISTEN via pq.NewListener (which reconnects by itself):

  • new NotifyChannel field, defaults to nostr_events
  • events that fit in a pg_notify payload (8000 bytes) travel inline; bigger ones are announced by id and read back from the table by the receiver, so only ephemeral events above the limit are lost
  • Notifications needs DatabaseURL since LISTEN takes over a dedicated connection

Tests

test/notify_test.go runs two backends on one embedded postgres and checks that a small event, an over-limit event (with full content read back) and an ephemeral event notified through one arrive on both, and that cancelling the context closes the channels.

Once released, relayer can switch to type Notifier = eventstore.Notifier.

A relay running as several processes on one database has no way to push
an event accepted by one process to the subscribers of the others.
Notifier is an optional interface for stores that can propagate events
between such processes: Notify is called by the relay for every
accepted event and Notifications delivers what every process notified.

PostgresBackend implements it with pg_notify on a configurable channel.
Events that fit in a pg_notify payload travel inline; bigger ones are
announced by id and read back from the table by the receiver, so only
ephemeral events above the limit are lost.
@mattn
mattn merged commit 0290e2d into fiatjaf:master Sep 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant