@fedify/postgres 2.0.0-dev.279 → 2.0.0-dev.323
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/dist/mq.cjs +53 -18
- package/dist/mq.js +53 -18
- package/package.json +3 -3
package/dist/mq.cjs
CHANGED
|
@@ -113,42 +113,77 @@ var PostgresMessageQueue = class {
|
|
|
113
113
|
const { signal } = options;
|
|
114
114
|
const poll = async () => {
|
|
115
115
|
while (!signal?.aborted) {
|
|
116
|
+
let processed = false;
|
|
116
117
|
const query = this.#sql`
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
SELECT id
|
|
118
|
+
WITH candidate AS (
|
|
119
|
+
SELECT id, ordering_key
|
|
120
120
|
FROM ${this.#sql(this.#tableName)}
|
|
121
121
|
WHERE created + delay < CURRENT_TIMESTAMP
|
|
122
|
-
AND
|
|
123
|
-
OR pg_try_advisory_lock(
|
|
124
|
-
hashtext(${this.#tableName}),
|
|
125
|
-
hashtext(ordering_key)
|
|
126
|
-
))
|
|
122
|
+
AND ordering_key IS NULL
|
|
127
123
|
ORDER BY created
|
|
128
124
|
LIMIT 1
|
|
125
|
+
FOR UPDATE SKIP LOCKED
|
|
129
126
|
)
|
|
127
|
+
DELETE FROM ${this.#sql(this.#tableName)}
|
|
128
|
+
WHERE id IN (SELECT id FROM candidate)
|
|
130
129
|
RETURNING message, ordering_key;
|
|
131
130
|
`.execute();
|
|
132
131
|
const cancel = query.cancel.bind(query);
|
|
133
132
|
signal?.addEventListener("abort", cancel);
|
|
134
|
-
let i = 0;
|
|
135
133
|
for (const row of await query) {
|
|
136
134
|
if (signal?.aborted) return;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
135
|
+
await handler(row.message);
|
|
136
|
+
processed = true;
|
|
137
|
+
}
|
|
138
|
+
signal?.removeEventListener("abort", cancel);
|
|
139
|
+
if (processed) continue;
|
|
140
|
+
const attemptedOrderingKeys = /* @__PURE__ */ new Set();
|
|
141
|
+
while (!signal?.aborted) {
|
|
142
|
+
const candidateResult = await this.#sql`
|
|
143
|
+
SELECT id, ordering_key
|
|
144
|
+
FROM ${this.#sql(this.#tableName)}
|
|
145
|
+
WHERE created + delay < CURRENT_TIMESTAMP
|
|
146
|
+
AND ordering_key IS NOT NULL
|
|
147
|
+
${attemptedOrderingKeys.size > 0 ? this.#sql`AND ordering_key NOT IN ${this.#sql([...attemptedOrderingKeys])}` : this.#sql``}
|
|
148
|
+
ORDER BY created
|
|
149
|
+
LIMIT 1
|
|
150
|
+
`;
|
|
151
|
+
if (candidateResult.length === 0) break;
|
|
152
|
+
const candidate = candidateResult[0];
|
|
153
|
+
const candidateId = candidate.id;
|
|
154
|
+
const orderingKey = candidate.ordering_key;
|
|
155
|
+
attemptedOrderingKeys.add(orderingKey);
|
|
156
|
+
const lockResult = await this.#sql`
|
|
157
|
+
SELECT pg_try_advisory_lock(
|
|
158
|
+
hashtext(${this.#tableName}),
|
|
159
|
+
hashtext(${orderingKey})
|
|
160
|
+
) AS acquired
|
|
161
|
+
`;
|
|
162
|
+
if (lockResult[0].acquired) {
|
|
163
|
+
try {
|
|
164
|
+
const deleteResult = await this.#sql`
|
|
165
|
+
DELETE FROM ${this.#sql(this.#tableName)}
|
|
166
|
+
WHERE id = ${candidateId}
|
|
167
|
+
RETURNING message, ordering_key
|
|
168
|
+
`;
|
|
169
|
+
for (const row of deleteResult) {
|
|
170
|
+
if (signal?.aborted) return;
|
|
171
|
+
await handler(row.message);
|
|
172
|
+
processed = true;
|
|
173
|
+
}
|
|
174
|
+
} finally {
|
|
175
|
+
await this.#sql`
|
|
142
176
|
SELECT pg_advisory_unlock(
|
|
143
177
|
hashtext(${this.#tableName}),
|
|
144
178
|
hashtext(${orderingKey})
|
|
145
|
-
)
|
|
179
|
+
)
|
|
146
180
|
`;
|
|
181
|
+
}
|
|
182
|
+
if (processed) break;
|
|
147
183
|
}
|
|
148
|
-
i++;
|
|
149
184
|
}
|
|
150
|
-
|
|
151
|
-
|
|
185
|
+
if (processed) continue;
|
|
186
|
+
break;
|
|
152
187
|
}
|
|
153
188
|
};
|
|
154
189
|
const timeouts = /* @__PURE__ */ new Set();
|
package/dist/mq.js
CHANGED
|
@@ -112,42 +112,77 @@ var PostgresMessageQueue = class {
|
|
|
112
112
|
const { signal } = options;
|
|
113
113
|
const poll = async () => {
|
|
114
114
|
while (!signal?.aborted) {
|
|
115
|
+
let processed = false;
|
|
115
116
|
const query = this.#sql`
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
SELECT id
|
|
117
|
+
WITH candidate AS (
|
|
118
|
+
SELECT id, ordering_key
|
|
119
119
|
FROM ${this.#sql(this.#tableName)}
|
|
120
120
|
WHERE created + delay < CURRENT_TIMESTAMP
|
|
121
|
-
AND
|
|
122
|
-
OR pg_try_advisory_lock(
|
|
123
|
-
hashtext(${this.#tableName}),
|
|
124
|
-
hashtext(ordering_key)
|
|
125
|
-
))
|
|
121
|
+
AND ordering_key IS NULL
|
|
126
122
|
ORDER BY created
|
|
127
123
|
LIMIT 1
|
|
124
|
+
FOR UPDATE SKIP LOCKED
|
|
128
125
|
)
|
|
126
|
+
DELETE FROM ${this.#sql(this.#tableName)}
|
|
127
|
+
WHERE id IN (SELECT id FROM candidate)
|
|
129
128
|
RETURNING message, ordering_key;
|
|
130
129
|
`.execute();
|
|
131
130
|
const cancel = query.cancel.bind(query);
|
|
132
131
|
signal?.addEventListener("abort", cancel);
|
|
133
|
-
let i = 0;
|
|
134
132
|
for (const row of await query) {
|
|
135
133
|
if (signal?.aborted) return;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
await handler(row.message);
|
|
135
|
+
processed = true;
|
|
136
|
+
}
|
|
137
|
+
signal?.removeEventListener("abort", cancel);
|
|
138
|
+
if (processed) continue;
|
|
139
|
+
const attemptedOrderingKeys = /* @__PURE__ */ new Set();
|
|
140
|
+
while (!signal?.aborted) {
|
|
141
|
+
const candidateResult = await this.#sql`
|
|
142
|
+
SELECT id, ordering_key
|
|
143
|
+
FROM ${this.#sql(this.#tableName)}
|
|
144
|
+
WHERE created + delay < CURRENT_TIMESTAMP
|
|
145
|
+
AND ordering_key IS NOT NULL
|
|
146
|
+
${attemptedOrderingKeys.size > 0 ? this.#sql`AND ordering_key NOT IN ${this.#sql([...attemptedOrderingKeys])}` : this.#sql``}
|
|
147
|
+
ORDER BY created
|
|
148
|
+
LIMIT 1
|
|
149
|
+
`;
|
|
150
|
+
if (candidateResult.length === 0) break;
|
|
151
|
+
const candidate = candidateResult[0];
|
|
152
|
+
const candidateId = candidate.id;
|
|
153
|
+
const orderingKey = candidate.ordering_key;
|
|
154
|
+
attemptedOrderingKeys.add(orderingKey);
|
|
155
|
+
const lockResult = await this.#sql`
|
|
156
|
+
SELECT pg_try_advisory_lock(
|
|
157
|
+
hashtext(${this.#tableName}),
|
|
158
|
+
hashtext(${orderingKey})
|
|
159
|
+
) AS acquired
|
|
160
|
+
`;
|
|
161
|
+
if (lockResult[0].acquired) {
|
|
162
|
+
try {
|
|
163
|
+
const deleteResult = await this.#sql`
|
|
164
|
+
DELETE FROM ${this.#sql(this.#tableName)}
|
|
165
|
+
WHERE id = ${candidateId}
|
|
166
|
+
RETURNING message, ordering_key
|
|
167
|
+
`;
|
|
168
|
+
for (const row of deleteResult) {
|
|
169
|
+
if (signal?.aborted) return;
|
|
170
|
+
await handler(row.message);
|
|
171
|
+
processed = true;
|
|
172
|
+
}
|
|
173
|
+
} finally {
|
|
174
|
+
await this.#sql`
|
|
141
175
|
SELECT pg_advisory_unlock(
|
|
142
176
|
hashtext(${this.#tableName}),
|
|
143
177
|
hashtext(${orderingKey})
|
|
144
|
-
)
|
|
178
|
+
)
|
|
145
179
|
`;
|
|
180
|
+
}
|
|
181
|
+
if (processed) break;
|
|
146
182
|
}
|
|
147
|
-
i++;
|
|
148
183
|
}
|
|
149
|
-
|
|
150
|
-
|
|
184
|
+
if (processed) continue;
|
|
185
|
+
break;
|
|
151
186
|
}
|
|
152
187
|
};
|
|
153
188
|
const timeouts = /* @__PURE__ */ new Set();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/postgres",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.323+1d796545",
|
|
4
4
|
"description": "PostgreSQL drivers for Fedify",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fedify",
|
|
@@ -74,14 +74,14 @@
|
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"postgres": "^3.4.7",
|
|
77
|
-
"@fedify/fedify": "^2.0.0-dev.
|
|
77
|
+
"@fedify/fedify": "^2.0.0-dev.323+1d796545"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@std/async": "npm:@jsr/std__async@^1.0.13",
|
|
81
81
|
"tsdown": "^0.12.9",
|
|
82
82
|
"typescript": "^5.9.3",
|
|
83
83
|
"@fedify/fixture": "^2.0.0",
|
|
84
|
-
"@fedify/testing": "^2.0.0-dev.
|
|
84
|
+
"@fedify/testing": "^2.0.0-dev.323+1d796545"
|
|
85
85
|
},
|
|
86
86
|
"scripts": {
|
|
87
87
|
"build:self": "tsdown",
|