@unchainedshop/core-orders 4.8.21 → 4.8.23
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.
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { mongodb } from '@unchainedshop/mongodb';
|
|
2
|
+
export interface OrderLock {
|
|
3
|
+
key: string;
|
|
4
|
+
uniqueValue: string;
|
|
5
|
+
expireAt: Date;
|
|
6
|
+
}
|
|
7
|
+
export declare const OrderLocksCollection: (db: mongodb.Db) => Promise<mongodb.Collection<OrderLock>>;
|
|
8
|
+
export declare const acquireLock: (OrderLocks: mongodb.Collection<OrderLock>, key: string, ttl: number) => Promise<{
|
|
9
|
+
release: () => Promise<void>;
|
|
10
|
+
}>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mongodb, buildDbIndexes } from '@unchainedshop/mongodb';
|
|
2
|
+
import { setTimeout as sleep } from 'node:timers/promises';
|
|
3
|
+
const DUPLICATE_KEY = 11000;
|
|
4
|
+
const LOCK_RETRIES = 10;
|
|
5
|
+
const LOCK_RETRY_DELAY_MS = 200;
|
|
6
|
+
export const OrderLocksCollection = async (db) => {
|
|
7
|
+
const OrderLocks = db.collection('locco-locks');
|
|
8
|
+
const success = await buildDbIndexes(OrderLocks, [
|
|
9
|
+
{ index: { key: 1 }, options: { unique: true } },
|
|
10
|
+
{ index: { expireAt: 1 }, options: { expireAfterSeconds: 0 } },
|
|
11
|
+
], { rebuild: false });
|
|
12
|
+
if (!success) {
|
|
13
|
+
throw new Error('Could not ensure the unique index backing order locks, refusing to start');
|
|
14
|
+
}
|
|
15
|
+
return OrderLocks;
|
|
16
|
+
};
|
|
17
|
+
export const acquireLock = async (OrderLocks, key, ttl) => {
|
|
18
|
+
const uniqueValue = crypto.randomUUID();
|
|
19
|
+
for (let attempt = 0; attempt < LOCK_RETRIES; attempt += 1) {
|
|
20
|
+
try {
|
|
21
|
+
await OrderLocks.updateOne({ key, expireAt: { $lt: new Date() } }, { $set: { key, uniqueValue, expireAt: new Date(Date.now() + ttl) } }, { upsert: true });
|
|
22
|
+
return {
|
|
23
|
+
release: async () => {
|
|
24
|
+
try {
|
|
25
|
+
await OrderLocks.deleteOne({ key, uniqueValue, expireAt: { $gt: new Date() } });
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error?.code !== DUPLICATE_KEY)
|
|
34
|
+
throw error;
|
|
35
|
+
if (attempt < LOCK_RETRIES - 1)
|
|
36
|
+
await sleep(LOCK_RETRY_DELAY_MS);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`Could not acquire lock ${key}`);
|
|
40
|
+
};
|
|
@@ -115,7 +115,9 @@ export declare const configureOrdersModule: ({ db, migrationRepository, options:
|
|
|
115
115
|
status: OrderStatus | null;
|
|
116
116
|
info?: string;
|
|
117
117
|
}) => Promise<mongodb.WithId<Order> | null>;
|
|
118
|
-
acquireLock: (orderId: string, identifier: string, timeout?: number) => Promise<
|
|
118
|
+
acquireLock: (orderId: string, identifier: string, timeout?: number) => Promise<{
|
|
119
|
+
release: () => Promise<void>;
|
|
120
|
+
}>;
|
|
119
121
|
setDeliveryProvider: (orderId: string, deliveryProviderId: string) => Promise<mongodb.WithId<Order> | null>;
|
|
120
122
|
setPaymentProvider: (orderId: string, paymentProviderId: string) => Promise<mongodb.WithId<Order> | null>;
|
|
121
123
|
create: ({ userId, orderNumber, currencyCode, countryCode, billingAddress, contact, context, }: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Locker, MongoAdapter } from '@kontsedal/locco';
|
|
2
1
|
import { generateDbFilterById, mongodb } from '@unchainedshop/mongodb';
|
|
3
2
|
import { OrderDeliveriesCollection } from "../db/OrderDeliveriesCollection.js";
|
|
3
|
+
import { OrderLocksCollection, acquireLock } from "../db/OrderLocksCollection.js";
|
|
4
4
|
import { OrderDiscountsCollection } from "../db/OrderDiscountsCollection.js";
|
|
5
5
|
import { OrderPaymentsCollection } from "../db/OrderPaymentsCollection.js";
|
|
6
6
|
import { OrderPositionsCollection } from "../db/OrderPositionsCollection.js";
|
|
@@ -31,15 +31,7 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
|
|
|
31
31
|
const OrderDiscounts = await OrderDiscountsCollection(db);
|
|
32
32
|
const OrderPayments = await OrderPaymentsCollection(db);
|
|
33
33
|
const OrderPositions = await OrderPositionsCollection(db);
|
|
34
|
-
const
|
|
35
|
-
client: {
|
|
36
|
-
db: () => db,
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
const locker = new Locker({
|
|
40
|
-
adapter: mongoAdapter,
|
|
41
|
-
retrySettings: { retryDelay: 200, retryTimes: 10 },
|
|
42
|
-
});
|
|
34
|
+
const OrderLocks = await OrderLocksCollection(db);
|
|
43
35
|
const orderQueries = configureOrdersModuleQueries({ Orders });
|
|
44
36
|
const orderMutations = configureOrderModuleMutations({
|
|
45
37
|
Orders,
|
|
@@ -139,7 +131,7 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
|
|
|
139
131
|
return modificationResult.value || Orders.findOne(selector, {});
|
|
140
132
|
},
|
|
141
133
|
acquireLock: async (orderId, identifier, timeout = 5000) => {
|
|
142
|
-
return
|
|
134
|
+
return acquireLock(OrderLocks, `order:${identifier}:${orderId}`, timeout);
|
|
143
135
|
},
|
|
144
136
|
setDeliveryProvider: async (orderId, deliveryProviderId) => {
|
|
145
137
|
const delivery = await OrderDeliveries.findOne({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/core-orders",
|
|
3
3
|
"description": "Order management module for the Unchained Engine",
|
|
4
|
-
"version": "4.8.
|
|
4
|
+
"version": "4.8.23",
|
|
5
5
|
"main": "lib/orders-index.js",
|
|
6
6
|
"types": "lib/orders-index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -35,9 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@kontsedal/locco": "^1.1.0",
|
|
39
38
|
"@unchainedshop/events": "^4.8.12",
|
|
40
|
-
"@unchainedshop/
|
|
39
|
+
"@unchainedshop/mongodb": "^4.8.12",
|
|
41
40
|
"@unchainedshop/utils": "^4.8.12"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|