-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathindex.ts
More file actions
66 lines (66 loc) · 2.77 KB
/
Copy pathindex.ts
File metadata and controls
66 lines (66 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*!
* Copyright (c) 2018, imqueue.com <support@imqueue.com>
*
* I'm Queue Software Project
* Copyright (C) 2025 imqueue.com <support@imqueue.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* If you want to use this code in a closed source (commercial) project, you can
* purchase a proprietary commercial license. Please contact us at
* <support@imqueue.com> to get commercial licensing options.
*/
/**
* Reliable PostgreSQL LISTEN/NOTIFY for Node.js — with an inter-process lock so
* a horizontally scaled service handles each notification once.
*
* Start from {@link PgPubSub}: construct it with {@link PgPubSubOptions},
* subscribe channels inside its `'connect'` handler, and read messages from the
* instance's `'message'` event or from the per-channel emitter on `channels`.
*
* @remarks
* The problem this solves is that LISTEN/NOTIFY is a broadcast: every listening
* connection receives every notification, so a service scaled to N replicas
* handles each message N times. With `singleListener` on — the default — the
* replicas compete for a per-channel lock held as a row in PostgreSQL, and only
* the holder listens. The others stay connected as hot standbys.
*
* That makes delivery at-most-once, and the trade is worth stating plainly:
* NOTIFY has no backlog, so anything published while no process holds the lock
* is gone. A clean shutdown releases the lock and a standby takes over at once;
* an unclean exit leaves the channel unhandled until the next retry, bounded by
* `ACQUIRE_INTERVAL`. Payloads are also capped at 8000 bytes by PostgreSQL.
* Where losing a message is unacceptable, pair this with a durable queue rather
* than replacing one.
*
* @example
* ```typescript
* import { type AnyJson, PgPubSub } from '@imqueue/pg-pubsub';
*
* const pubSub = new PgPubSub({ connectionString: process.env.DB_URL });
*
* pubSub.on('connect', async () => {
* await pubSub.listen('UserChanged');
* });
* pubSub.on('message', (channel: string, payload: AnyJson) =>
* console.log(channel, payload),
* );
*
* await pubSub.connect();
* await pubSub.notify('UserChanged', { id: 1 });
* ```
*
* @packageDocumentation
*/
export * from './src/index.js';