@fedify/redis 0.3.0-dev.12 → 0.3.0

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/README.md CHANGED
@@ -64,7 +64,7 @@ Changelog
64
64
 
65
65
  ### Version 0.3.0
66
66
 
67
- To be released.
67
+ Released on October 4, 2024.
68
68
 
69
69
  - Polling is now more efficient.
70
70
  - Renamed `RedisMessageQueueOptions.loopInterval` option to `pollInterval`
package/esm/src/mq.js CHANGED
@@ -12,7 +12,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
12
12
  var _RedisMessageQueue_instances, _RedisMessageQueue_redis, _RedisMessageQueue_subRedis, _RedisMessageQueue_workerId, _RedisMessageQueue_channelKey, _RedisMessageQueue_queueKey, _RedisMessageQueue_lockKey, _RedisMessageQueue_codec, _RedisMessageQueue_pollIntervalMs, _RedisMessageQueue_loopHandle, _RedisMessageQueue_poll;
13
13
  // deno-lint-ignore-file no-explicit-any
14
14
  import * as dntShim from "../_dnt.shims.js";
15
+ import { getLogger } from "@logtape/logtape";
15
16
  import { JsonCodec } from "./codec.js";
17
+ const logger = getLogger(["fedify", "redis", "mq"]);
16
18
  /**
17
19
  * A message queue that uses Redis as the underlying storage.
18
20
  *
@@ -58,7 +60,10 @@ export class RedisMessageQueue {
58
60
  const ts = options?.delay == null
59
61
  ? 0
60
62
  : dntShim.Temporal.Now.instant().add(options.delay).epochMilliseconds;
61
- const encodedMessage = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").encode(message);
63
+ const encodedMessage = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").encode([
64
+ crypto.randomUUID(),
65
+ message,
66
+ ]);
62
67
  await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zadd(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), ts, encodedMessage);
63
68
  if (ts < 1)
64
69
  __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").publish(__classPrivateFieldGet(this, _RedisMessageQueue_channelKey, "f"), "");
@@ -74,7 +79,8 @@ export class RedisMessageQueue {
74
79
  try {
75
80
  message = await __classPrivateFieldGet(this, _RedisMessageQueue_instances, "m", _RedisMessageQueue_poll).call(this);
76
81
  }
77
- catch {
82
+ catch (error) {
83
+ logger.error("Error polling for messages: {error}", error);
78
84
  return;
79
85
  }
80
86
  if (message === undefined)
@@ -115,17 +121,22 @@ export class RedisMessageQueue {
115
121
  });
116
122
  }
117
123
  [(_RedisMessageQueue_redis = new WeakMap(), _RedisMessageQueue_subRedis = new WeakMap(), _RedisMessageQueue_workerId = new WeakMap(), _RedisMessageQueue_channelKey = new WeakMap(), _RedisMessageQueue_queueKey = new WeakMap(), _RedisMessageQueue_lockKey = new WeakMap(), _RedisMessageQueue_codec = new WeakMap(), _RedisMessageQueue_pollIntervalMs = new WeakMap(), _RedisMessageQueue_loopHandle = new WeakMap(), _RedisMessageQueue_instances = new WeakSet(), _RedisMessageQueue_poll = async function _RedisMessageQueue_poll() {
118
- const result = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").setnx(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_workerId, "f"));
119
- if (result < 1)
124
+ logger.debug("Polling for messages...");
125
+ const result = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").set(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_workerId, "f"), "EX", Math.floor(__classPrivateFieldGet(this, _RedisMessageQueue_pollIntervalMs, "f") / 1000 * 2), "NX");
126
+ if (result == null) {
127
+ logger.debug("Another worker is already processing messages; skipping...");
120
128
  return;
121
- await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").expire(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_pollIntervalMs, "f") / 1000 * 2);
129
+ }
130
+ logger.debug("Acquired lock; processing messages...");
122
131
  const messages = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrangebyscoreBuffer(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), 0, dntShim.Temporal.Now.instant().epochMilliseconds);
132
+ logger.debug("Found {messages} messages to process.", { messages: messages.length });
123
133
  try {
124
134
  if (messages.length < 1)
125
135
  return;
126
- const message = messages[0];
127
- await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrem(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), message);
128
- return __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").decode(message);
136
+ const encodedMessage = messages[0];
137
+ await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrem(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), encodedMessage);
138
+ const [_, message] = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").decode(encodedMessage);
139
+ return message;
129
140
  }
130
141
  finally {
131
142
  await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").del(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/redis",
3
- "version": "0.3.0-dev.12+c328aa31",
3
+ "version": "0.3.0",
4
4
  "description": "Redis drivers for Fedify",
5
5
  "keywords": [
6
6
  "fedify",
@@ -60,7 +60,8 @@
60
60
  ],
61
61
  "dependencies": {
62
62
  "@fedify/fedify": "^1.0.0",
63
- "ioredis": "^5.4.0",
63
+ "@logtape/logtape": "^0.6.3",
64
+ "ioredis": "^5.4.1",
64
65
  "@deno/shim-deno": "~0.18.0",
65
66
  "@js-temporal/polyfill": "^0.4.4"
66
67
  },
package/script/src/mq.js CHANGED
@@ -38,7 +38,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.RedisMessageQueue = void 0;
39
39
  // deno-lint-ignore-file no-explicit-any
40
40
  const dntShim = __importStar(require("../_dnt.shims.js"));
41
+ const logtape_1 = require("@logtape/logtape");
41
42
  const codec_js_1 = require("./codec.js");
43
+ const logger = (0, logtape_1.getLogger)(["fedify", "redis", "mq"]);
42
44
  /**
43
45
  * A message queue that uses Redis as the underlying storage.
44
46
  *
@@ -84,7 +86,10 @@ class RedisMessageQueue {
84
86
  const ts = options?.delay == null
85
87
  ? 0
86
88
  : dntShim.Temporal.Now.instant().add(options.delay).epochMilliseconds;
87
- const encodedMessage = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").encode(message);
89
+ const encodedMessage = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").encode([
90
+ crypto.randomUUID(),
91
+ message,
92
+ ]);
88
93
  await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zadd(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), ts, encodedMessage);
89
94
  if (ts < 1)
90
95
  __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").publish(__classPrivateFieldGet(this, _RedisMessageQueue_channelKey, "f"), "");
@@ -100,7 +105,8 @@ class RedisMessageQueue {
100
105
  try {
101
106
  message = await __classPrivateFieldGet(this, _RedisMessageQueue_instances, "m", _RedisMessageQueue_poll).call(this);
102
107
  }
103
- catch {
108
+ catch (error) {
109
+ logger.error("Error polling for messages: {error}", error);
104
110
  return;
105
111
  }
106
112
  if (message === undefined)
@@ -141,17 +147,22 @@ class RedisMessageQueue {
141
147
  });
142
148
  }
143
149
  [(_RedisMessageQueue_redis = new WeakMap(), _RedisMessageQueue_subRedis = new WeakMap(), _RedisMessageQueue_workerId = new WeakMap(), _RedisMessageQueue_channelKey = new WeakMap(), _RedisMessageQueue_queueKey = new WeakMap(), _RedisMessageQueue_lockKey = new WeakMap(), _RedisMessageQueue_codec = new WeakMap(), _RedisMessageQueue_pollIntervalMs = new WeakMap(), _RedisMessageQueue_loopHandle = new WeakMap(), _RedisMessageQueue_instances = new WeakSet(), _RedisMessageQueue_poll = async function _RedisMessageQueue_poll() {
144
- const result = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").setnx(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_workerId, "f"));
145
- if (result < 1)
150
+ logger.debug("Polling for messages...");
151
+ const result = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").set(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_workerId, "f"), "EX", Math.floor(__classPrivateFieldGet(this, _RedisMessageQueue_pollIntervalMs, "f") / 1000 * 2), "NX");
152
+ if (result == null) {
153
+ logger.debug("Another worker is already processing messages; skipping...");
146
154
  return;
147
- await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").expire(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"), __classPrivateFieldGet(this, _RedisMessageQueue_pollIntervalMs, "f") / 1000 * 2);
155
+ }
156
+ logger.debug("Acquired lock; processing messages...");
148
157
  const messages = await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrangebyscoreBuffer(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), 0, dntShim.Temporal.Now.instant().epochMilliseconds);
158
+ logger.debug("Found {messages} messages to process.", { messages: messages.length });
149
159
  try {
150
160
  if (messages.length < 1)
151
161
  return;
152
- const message = messages[0];
153
- await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrem(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), message);
154
- return __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").decode(message);
162
+ const encodedMessage = messages[0];
163
+ await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").zrem(__classPrivateFieldGet(this, _RedisMessageQueue_queueKey, "f"), encodedMessage);
164
+ const [_, message] = __classPrivateFieldGet(this, _RedisMessageQueue_codec, "f").decode(encodedMessage);
165
+ return message;
155
166
  }
156
167
  finally {
157
168
  await __classPrivateFieldGet(this, _RedisMessageQueue_redis, "f").del(__classPrivateFieldGet(this, _RedisMessageQueue_lockKey, "f"));
@@ -1 +1 @@
1
- {"version":3,"file":"mq.d.ts","sourceRoot":"","sources":["../../src/src/mq.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EACV,YAAY,EACZ,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC1E;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,YAAY,EAAE,UAAU;;IAWhE;;;;OAIG;gBACS,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,GAAE,wBAA6B;IAahE,OAAO,CACX,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,IAAI,CAAC;IA+BV,MAAM,CACV,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/C,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,IAAI,CAAC;IAmDhB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAKzB"}
1
+ {"version":3,"file":"mq.d.ts","sourceRoot":"","sources":["../../src/src/mq.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,EACV,YAAY,EACZ,0BAA0B,EAC1B,yBAAyB,EAC1B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,KAAK,KAAK,EAAa,MAAM,YAAY,CAAC;AAInD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,QAAQ,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IAEd;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC1E;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,YAAY,EAAE,UAAU;;IAWhE;;;;OAIG;gBACS,KAAK,EAAE,MAAM,KAAK,EAAE,OAAO,GAAE,wBAA6B;IAahE,OAAO,CACX,OAAO,EAAE,GAAG,EACZ,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC,IAAI,CAAC;IAgDV,MAAM,CACV,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/C,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,IAAI,CAAC;IAoDhB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;CAKzB"}