@nitra/nats 4.2.0 → 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli.js +2 -1
- package/src/consumer.js +26 -27
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -28,7 +28,8 @@ function parseConsumerYaml() {
|
|
|
28
28
|
durableName: data.spec?.durableName,
|
|
29
29
|
filterSubjects: data.spec?.filterSubjects,
|
|
30
30
|
deliverPolicy: data.spec?.deliverPolicy,
|
|
31
|
-
ackPolicy: data.spec?.ackPolicy
|
|
31
|
+
ackPolicy: data.spec?.ackPolicy,
|
|
32
|
+
ackWait: data.spec?.ackWait
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
} catch (error) {
|
package/src/consumer.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsm } from './nats.js'
|
|
2
2
|
import { log } from '@nitra/pino'
|
|
3
|
+
import { nanos, millis } from '@nats-io/nats-core'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Створює або оновлює consumer.
|
|
@@ -22,68 +23,66 @@ export async function ensureConsumer(spec) {
|
|
|
22
23
|
// якщо не вказати, то consumer буде слухати всі повідомлення зі stream
|
|
23
24
|
spec.filterSubjects = spec.filterSubjects.map(fs => `${spec.streamName}.${fs}`)
|
|
24
25
|
|
|
26
|
+
const preparedSpec = prepareSpec(spec)
|
|
27
|
+
|
|
25
28
|
// якщо не існує consumer-а створюємо його. якщо є перевіримо чи відповідає spec(якщо ні, то перестворюємо або оновлюємо)
|
|
26
29
|
if (consumer) {
|
|
27
30
|
log.info(`✅ Consumer «${spec.durableName}» already exists`)
|
|
28
31
|
|
|
29
|
-
const { filter_subjects, deliver_policy, ack_policy } = consumer.config
|
|
32
|
+
const { filter_subjects, deliver_policy, ack_policy, ack_wait } = consumer.config
|
|
30
33
|
|
|
31
34
|
// якщо deliver_policy або ack_policy не відповідають spec, то перестворюємо consumer
|
|
32
35
|
if (deliver_policy !== spec.deliverPolicy || ack_policy !== spec.ackPolicy) {
|
|
33
|
-
const tempSpec =
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
filterSubjects: spec.filterSubjects,
|
|
37
|
-
deliverPolicy: deliver_policy,
|
|
38
|
-
ackPolicy: ack_policy
|
|
39
|
-
}
|
|
36
|
+
const tempSpec = preparedSpec
|
|
37
|
+
tempSpec.durable_name = `temp_${preparedSpec.durable_name}`
|
|
38
|
+
|
|
40
39
|
// Цей “тимчасовий consumer” потрібен як страховка на час перестворення,
|
|
41
40
|
// щоб не втратити повідомлення у стрімі з retention: 'interest'
|
|
42
|
-
await
|
|
41
|
+
await jsm.consumers.add(spec.streamName, tempSpec)
|
|
43
42
|
// delete old consumer
|
|
44
43
|
await jsm.consumers.delete(spec.streamName, spec.durableName)
|
|
45
44
|
// create new consumer
|
|
46
|
-
await
|
|
45
|
+
await jsm.consumers.add(spec.streamName, preparedSpec)
|
|
46
|
+
|
|
47
47
|
// delete temp consumer
|
|
48
|
-
await jsm.consumers.delete(
|
|
48
|
+
await jsm.consumers.delete(spec.streamName, tempSpec.durable_name)
|
|
49
49
|
|
|
50
50
|
log.info(`🔥 Consumer «${spec.durableName}» - recreated`)
|
|
51
51
|
}
|
|
52
52
|
// якщо filter_subjects не відповідають spec, то оновлюємо consumer
|
|
53
|
-
else if (
|
|
53
|
+
else if (
|
|
54
|
+
compareArrays(spec.filterSubjects, filter_subjects) &&
|
|
55
|
+
(spec.ackWait === undefined || spec.ackWait === millis(ack_wait ?? 0))
|
|
56
|
+
) {
|
|
54
57
|
log.info(`✅ Consumer «${spec.durableName}» - no changes`)
|
|
55
58
|
} else {
|
|
56
|
-
await jsm.consumers.update(spec.streamName, spec.durableName,
|
|
57
|
-
filter_subjects: spec.filterSubjects
|
|
58
|
-
})
|
|
59
|
+
await jsm.consumers.update(spec.streamName, spec.durableName, preparedSpec)
|
|
59
60
|
|
|
60
61
|
log.info(`🔥 Consumer «${spec.durableName}» filter_subjects - updated`)
|
|
61
62
|
}
|
|
62
63
|
} else {
|
|
63
|
-
await
|
|
64
|
+
await jsm.consumers.add(spec.streamName, preparedSpec)
|
|
64
65
|
log.info(`🔥 Consumer «${spec.durableName}» created`)
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/**
|
|
69
|
-
*
|
|
70
|
+
* Підготовляє специфікацію consumer-а для створення
|
|
70
71
|
* @param {object} spec - специфікація consumer-а
|
|
71
|
-
* @
|
|
72
|
-
* @param {string} spec.durableName - назва consumer-а
|
|
73
|
-
* @param {string[]} spec.filterSubjects - масив subject-ів для фільтрації
|
|
74
|
-
* @param {string} spec.deliverPolicy - політика доставки
|
|
75
|
-
* @param {string} spec.ackPolicy - політика підтвердження
|
|
76
|
-
* @returns {Promise<void>}
|
|
72
|
+
* @returns {object} підготовлена специфікація
|
|
77
73
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
function prepareSpec(spec) {
|
|
75
|
+
const preparedSpec = {
|
|
80
76
|
durable_name: spec.durableName,
|
|
81
77
|
ack_policy: spec.ackPolicy, // якщо не підтвердити повідомлення, воно буде повторно надіслано
|
|
82
78
|
filter_subjects: spec.filterSubjects,
|
|
83
79
|
deliver_policy: spec.deliverPolicy // 'all' - всі непрочитані повідомлення
|
|
84
|
-
}
|
|
80
|
+
}
|
|
81
|
+
if (spec.ackWait) {
|
|
82
|
+
preparedSpec.ack_wait = nanos(spec.ackWait)
|
|
83
|
+
}
|
|
84
|
+
return preparedSpec
|
|
85
85
|
}
|
|
86
|
-
|
|
87
86
|
/**
|
|
88
87
|
* Перевіряє наявність або створює JetStream stream.
|
|
89
88
|
* @param {string} streamName - назва stream
|