@matter/general 0.13.1-alpha.0-20250520-d699cd56d → 0.14.0-alpha.0-20250524-51a7e1721
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/cjs/polyfills/index.d.ts +1 -0
- package/dist/cjs/polyfills/index.d.ts.map +1 -1
- package/dist/cjs/polyfills/index.js +1 -0
- package/dist/cjs/polyfills/index.js.map +1 -1
- package/dist/cjs/polyfills/suppressed-error.d.ts +7 -0
- package/dist/cjs/polyfills/suppressed-error.d.ts.map +1 -0
- package/dist/cjs/polyfills/suppressed-error.js +21 -0
- package/dist/cjs/polyfills/suppressed-error.js.map +6 -0
- package/dist/cjs/transaction/Transaction.d.ts +49 -22
- package/dist/cjs/transaction/Transaction.d.ts.map +1 -1
- package/dist/cjs/transaction/Transaction.js +22 -3
- package/dist/cjs/transaction/Transaction.js.map +1 -1
- package/dist/cjs/transaction/Tx.d.ts +9 -4
- package/dist/cjs/transaction/Tx.d.ts.map +1 -1
- package/dist/cjs/transaction/Tx.js +152 -122
- package/dist/cjs/transaction/Tx.js.map +2 -2
- package/dist/cjs/util/Observable.js +1 -1
- package/dist/cjs/util/Observable.js.map +1 -1
- package/dist/esm/polyfills/index.d.ts +1 -0
- package/dist/esm/polyfills/index.d.ts.map +1 -1
- package/dist/esm/polyfills/index.js +1 -0
- package/dist/esm/polyfills/index.js.map +1 -1
- package/dist/esm/polyfills/suppressed-error.d.ts +7 -0
- package/dist/esm/polyfills/suppressed-error.d.ts.map +1 -0
- package/dist/esm/polyfills/suppressed-error.js +20 -0
- package/dist/esm/polyfills/suppressed-error.js.map +6 -0
- package/dist/esm/transaction/Transaction.d.ts +49 -22
- package/dist/esm/transaction/Transaction.d.ts.map +1 -1
- package/dist/esm/transaction/Transaction.js +23 -4
- package/dist/esm/transaction/Transaction.js.map +1 -1
- package/dist/esm/transaction/Tx.d.ts +9 -4
- package/dist/esm/transaction/Tx.d.ts.map +1 -1
- package/dist/esm/transaction/Tx.js +152 -122
- package/dist/esm/transaction/Tx.js.map +2 -2
- package/dist/esm/util/Observable.js +1 -1
- package/dist/esm/util/Observable.js.map +1 -1
- package/package.json +2 -2
- package/src/polyfills/index.ts +1 -0
- package/src/polyfills/suppressed-error.ts +27 -0
- package/src/transaction/Transaction.ts +42 -4
- package/src/transaction/Tx.ts +202 -165
- package/src/util/Observable.ts +1 -1
|
@@ -134,7 +134,9 @@ type ResourceSetType = ResourceSet;
|
|
|
134
134
|
type ParticipantType = Participant;
|
|
135
135
|
export declare const Transaction: {
|
|
136
136
|
/**
|
|
137
|
-
* Perform a transactional operation.
|
|
137
|
+
* Perform a transactional operation.
|
|
138
|
+
*
|
|
139
|
+
* This creates a read/write transaction scoped to the life of an optionally async function call.
|
|
138
140
|
*
|
|
139
141
|
* The transaction will commit automatically if it is exclusive (write mode) after the actor returns.
|
|
140
142
|
*
|
|
@@ -142,18 +144,25 @@ export declare const Transaction: {
|
|
|
142
144
|
* destroyed.
|
|
143
145
|
*/
|
|
144
146
|
act<T>(via: string, actor: (transaction: Transaction) => MaybePromise<T>): MaybePromise<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Create a transaction.
|
|
149
|
+
*
|
|
150
|
+
* Transactions must be closed using {@link Finalization#resolve} or {@link Finalization#reject}.
|
|
151
|
+
*
|
|
152
|
+
* When closed the transaction commits automatically if exclusive.
|
|
153
|
+
*/
|
|
154
|
+
open(via: string): Transaction & Transaction.Finalization;
|
|
145
155
|
ReadOnly: {
|
|
146
|
-
"__#
|
|
147
|
-
"__#
|
|
148
|
-
"__#
|
|
149
|
-
"__#
|
|
150
|
-
"__#
|
|
151
|
-
"__#
|
|
152
|
-
"__#
|
|
153
|
-
"__#
|
|
154
|
-
"__#
|
|
155
|
-
"__#
|
|
156
|
-
close(): void;
|
|
156
|
+
"__#15463@#participants": Set<Participant>;
|
|
157
|
+
"__#15463@#roles": Map<{}, Participant>;
|
|
158
|
+
"__#15463@#resources": Set<Resource>;
|
|
159
|
+
"__#15463@#status": Status;
|
|
160
|
+
"__#15463@#waitingOn"?: Iterable<Transaction>;
|
|
161
|
+
"__#15463@#via": string;
|
|
162
|
+
"__#15463@#shared"?: import("../index.js").Observable<[]>;
|
|
163
|
+
"__#15463@#closed"?: import("../index.js").Observable<[]>;
|
|
164
|
+
"__#15463@#isAsync": boolean;
|
|
165
|
+
"__#15463@#reportingLocks": boolean;
|
|
157
166
|
readonly via: string;
|
|
158
167
|
readonly status: Status;
|
|
159
168
|
readonly participants: Set<Participant>;
|
|
@@ -169,20 +178,25 @@ export declare const Transaction: {
|
|
|
169
178
|
beginSync(): void;
|
|
170
179
|
addParticipants(...participants: Participant[]): void;
|
|
171
180
|
getParticipant(role: {}): Participant | undefined;
|
|
172
|
-
commit(): MaybePromise
|
|
181
|
+
commit(): MaybePromise<void>;
|
|
182
|
+
resolve<T>(result: T): MaybePromise<Awaited<T>>;
|
|
173
183
|
rollback(): Promise<void> | undefined;
|
|
184
|
+
reject(cause: unknown): MaybePromise<never>;
|
|
185
|
+
"__#15463@#executeCommitCycle"(count: number): MaybePromise<void>;
|
|
174
186
|
waitFor(others: Set<Transaction>): Promise<void>;
|
|
175
187
|
toString(): string;
|
|
176
188
|
treatAsSlow(): void;
|
|
177
|
-
"__#
|
|
178
|
-
"__#
|
|
179
|
-
"__#
|
|
180
|
-
"__#
|
|
181
|
-
"__#
|
|
182
|
-
"__#
|
|
183
|
-
"__#
|
|
184
|
-
"__#
|
|
185
|
-
"__#
|
|
189
|
+
"__#15463@#finalize"(status: Status, why: string, finalizer: () => MaybePromise): Promise<void> | undefined;
|
|
190
|
+
"__#15463@#reset"(why: string): void;
|
|
191
|
+
"__#15463@#createPreCommitExecutor"(): () => MaybePromise<void>;
|
|
192
|
+
"__#15463@#executeCommit"(): MaybePromise;
|
|
193
|
+
"__#15463@#executeCommit1"(): MaybePromise;
|
|
194
|
+
"__#15463@#executeCommit2"(): Promise<void> | undefined;
|
|
195
|
+
"__#15463@#createPostCommitExecutor"(participants: Participant[]): () => MaybePromise;
|
|
196
|
+
"__#15463@#executeRollback"(): Promise<void> | undefined;
|
|
197
|
+
"__#15463@#locksChanged"(resources: Set<Resource>, how?: string): void;
|
|
198
|
+
"__#15463@#assertAvailable"(): void;
|
|
199
|
+
[Symbol.dispose](): void;
|
|
186
200
|
};
|
|
187
201
|
Status: typeof Status;
|
|
188
202
|
Resource: typeof Resource;
|
|
@@ -193,6 +207,19 @@ export declare namespace Transaction {
|
|
|
193
207
|
type Resource = ResourceType;
|
|
194
208
|
type ResourceSet = ResourceSetType;
|
|
195
209
|
type Participant = ParticipantType;
|
|
210
|
+
interface Disposable extends Transaction, AsyncDisposable {
|
|
211
|
+
close(): MaybePromise<void>;
|
|
212
|
+
}
|
|
213
|
+
interface Finalization {
|
|
214
|
+
/**
|
|
215
|
+
* Finish the transaction. If {@link result} is a promise this may result on commit or rollback.
|
|
216
|
+
*/
|
|
217
|
+
resolve<T>(result: T): MaybePromise<Awaited<T>>;
|
|
218
|
+
/**
|
|
219
|
+
* Roll back, close the transaction and throw an error.
|
|
220
|
+
*/
|
|
221
|
+
reject(cause: unknown): MaybePromise<never>;
|
|
222
|
+
}
|
|
196
223
|
}
|
|
197
224
|
export {};
|
|
198
225
|
//# sourceMappingURL=Transaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,WAAW;IACxB;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;IAElC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IAEtD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAElD;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAEjC;;;;;OAKG;IACH,YAAY,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtD;;;;;OAKG;IACH,gBAAgB,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAEjD;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,eAAe,CAAC,GAAG,YAAY,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,EAAE,GAAG,WAAW,GAAG,SAAS,CAAC;IAElD;;;;;;;OAOG;IACH,MAAM,IAAI,YAAY,CAAC;IAEvB;;;;;;;OAOG;IACH,QAAQ,IAAI,YAAY,CAAC;IAEzB;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,KAAK,UAAU,GAAG,MAAM,CAAC;AACzB,KAAK,YAAY,GAAG,QAAQ,CAAC;AAC7B,KAAK,eAAe,GAAG,WAAW,CAAC;AACnC,KAAK,eAAe,GAAG,WAAW,CAAC;AAEnC,eAAO,MAAM,WAAW;IACpB
|
|
1
|
+
{"version":3,"file":"Transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/Transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Resource } from "./Resource.js";
|
|
7
7
|
import { Status } from "./Status.js";
|
|
8
|
-
import { ReadOnlyTransaction,
|
|
8
|
+
import { ReadOnlyTransaction, open } from "./Tx.js";
|
|
9
9
|
const Transaction = {
|
|
10
10
|
/**
|
|
11
|
-
* Perform a transactional operation.
|
|
11
|
+
* Perform a transactional operation.
|
|
12
|
+
*
|
|
13
|
+
* This creates a read/write transaction scoped to the life of an optionally async function call.
|
|
12
14
|
*
|
|
13
15
|
* The transaction will commit automatically if it is exclusive (write mode) after the actor returns.
|
|
14
16
|
*
|
|
@@ -16,14 +18,31 @@ const Transaction = {
|
|
|
16
18
|
* destroyed.
|
|
17
19
|
*/
|
|
18
20
|
act(via, actor) {
|
|
19
|
-
|
|
21
|
+
const tx = open(via);
|
|
22
|
+
let result;
|
|
23
|
+
try {
|
|
24
|
+
result = actor(tx);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
return tx.reject(e);
|
|
27
|
+
}
|
|
28
|
+
return tx.resolve(result);
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Create a transaction.
|
|
32
|
+
*
|
|
33
|
+
* Transactions must be closed using {@link Finalization#resolve} or {@link Finalization#reject}.
|
|
34
|
+
*
|
|
35
|
+
* When closed the transaction commits automatically if exclusive.
|
|
36
|
+
*/
|
|
37
|
+
open(via) {
|
|
38
|
+
return open(via);
|
|
20
39
|
},
|
|
21
40
|
ReadOnly: ReadOnlyTransaction,
|
|
22
41
|
Status,
|
|
23
42
|
Resource,
|
|
24
43
|
[Symbol.toStringTag]: "Transaction"
|
|
25
44
|
};
|
|
26
|
-
Transaction.
|
|
45
|
+
Transaction.open = open;
|
|
27
46
|
export {
|
|
28
47
|
Transaction
|
|
29
48
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transaction/Transaction.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,SAAS,gBAAgB;AAEzB,SAAS,cAAc;AACvB,SAAS,qBAAqB,
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,SAAS,gBAAgB;AAEzB,SAAS,cAAc;AACvB,SAAS,qBAAqB,YAAY;AA+InC,MAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWvB,IAAO,KAAa,OAAuE;AACvF,UAAM,KAAK,KAAK,GAAG;AAEnB,QAAI;AACJ,QAAI;AACA,eAAS,MAAM,EAAE;AAAA,IACrB,SAAS,GAAG;AACR,aAAO,GAAG,OAAO,CAAC;AAAA,IACtB;AAEA,WAAO,GAAG,QAAQ,MAAM;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,KAAK,KAAa;AAEd,WAAO,KAAK,GAAG;AAAA,EACnB;AAAA,EAEA,UAAU;AAAA,EAEV;AAAA,EAEA;AAAA,EAEA,CAAC,OAAO,WAAW,GAAG;AAC1B;AAGA,YAAY,OAAO;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -11,20 +11,23 @@ import type { Transaction } from "./Transaction.js";
|
|
|
11
11
|
/**
|
|
12
12
|
* This is the only public interface to this file.
|
|
13
13
|
*/
|
|
14
|
-
export declare function
|
|
14
|
+
export declare function open(via: string): Transaction & Transaction.Finalization;
|
|
15
15
|
/**
|
|
16
16
|
* The concrete implementation of the Transaction interface.
|
|
17
17
|
*/
|
|
18
|
-
declare class Tx implements Transaction {
|
|
18
|
+
declare class Tx implements Transaction, Transaction.Finalization {
|
|
19
19
|
#private;
|
|
20
20
|
constructor(via: string, readonly?: boolean);
|
|
21
|
-
|
|
21
|
+
[Symbol.dispose](): void;
|
|
22
22
|
get via(): string;
|
|
23
23
|
get status(): Status;
|
|
24
24
|
get participants(): Set<Participant>;
|
|
25
25
|
get resources(): Set<Resource>;
|
|
26
26
|
get waitingOn(): Iterable<Transaction> | undefined;
|
|
27
27
|
get isAsync(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* We set this during async processing. This enables the lock reporting when too much time ellapses.
|
|
30
|
+
*/
|
|
28
31
|
set isAsync(isAsync: true);
|
|
29
32
|
onShared(listener: () => void, once?: boolean): void;
|
|
30
33
|
onClose(listener: () => void): void;
|
|
@@ -34,8 +37,10 @@ declare class Tx implements Transaction {
|
|
|
34
37
|
beginSync(): void;
|
|
35
38
|
addParticipants(...participants: Participant[]): void;
|
|
36
39
|
getParticipant(role: {}): Participant | undefined;
|
|
37
|
-
commit(): MaybePromise
|
|
40
|
+
commit(): MaybePromise<void>;
|
|
41
|
+
resolve<T>(result: T): MaybePromise<Awaited<T>>;
|
|
38
42
|
rollback(): Promise<void> | undefined;
|
|
43
|
+
reject(cause: unknown): MaybePromise<never>;
|
|
39
44
|
waitFor(others: Set<Transaction>): Promise<void>;
|
|
40
45
|
toString(): string;
|
|
41
46
|
treatAsSlow(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tx.d.ts","sourceRoot":"","sources":["../../../src/transaction/Tx.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"Tx.d.ts","sourceRoot":"","sources":["../../../src/transaction/Tx.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAUpD;;GAEG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC,YAAY,CAExE;AAED;;GAEG;AACH,cAAM,EAAG,YAAW,WAAW,EAAE,WAAW,CAAC,YAAY;;gBAYzC,GAAG,EAAE,MAAM,EAAE,QAAQ,UAAQ;IASzC,CAAC,MAAM,CAAC,OAAO,CAAC;IAMhB,IAAI,GAAG,WAEN;IAED,IAAI,MAAM,WAET;IAED,IAAI,YAAY,qBAEf;IAED,IAAI,SAAS,kBAEZ;IAED,IAAI,SAAS,sCAEZ;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACH,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,EAOxB;IAED,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO;IAW7C,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI;IAatB,YAAY,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE;IAY3C,gBAAgB,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE;IAgBnC,KAAK;IAsBX,SAAS;IAqBT,eAAe,CAAC,GAAG,YAAY,EAAE,WAAW,EAAE;IAyB9C,cAAc,CAAC,IAAI,EAAE,EAAE;IAMvB,MAAM;IAeN,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAiC/C,QAAQ;IAMR,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC;IAyE3C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC;IA6BhC,QAAQ;IAIR,WAAW;CAuYd;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAA2B,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { Diagnostic } from "#log/Diagnostic.js";
|
|
|
7
7
|
import { Logger } from "#log/Logger.js";
|
|
8
8
|
import { ImplementationError, ReadOnlyError } from "#MatterError.js";
|
|
9
9
|
import { Time } from "#time/Time.js";
|
|
10
|
+
import { asError } from "#util/Error.js";
|
|
10
11
|
import { Observable } from "#util/Observable.js";
|
|
11
12
|
import { MaybePromise } from "#util/Promises.js";
|
|
12
13
|
import { describeList } from "#util/String.js";
|
|
@@ -16,74 +17,8 @@ import { Status } from "./Status.js";
|
|
|
16
17
|
const logger = Logger.get("Transaction");
|
|
17
18
|
const MAX_PRECOMMIT_CYCLES = 5;
|
|
18
19
|
const MAX_CHAINED_COMMITS = 5;
|
|
19
|
-
function
|
|
20
|
-
|
|
21
|
-
let commits = 0;
|
|
22
|
-
function commitTransaction(finalResult) {
|
|
23
|
-
commits++;
|
|
24
|
-
if (commits > MAX_CHAINED_COMMITS) {
|
|
25
|
-
throw new TransactionFlowError(
|
|
26
|
-
`Transaction commits have cascaded ${MAX_CHAINED_COMMITS} times which likely indicates an infinite loop`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
const result = tx.commit();
|
|
30
|
-
if (MaybePromise.is(result)) {
|
|
31
|
-
return result.then(() => {
|
|
32
|
-
if (tx.status === Status.Exclusive) {
|
|
33
|
-
return commitTransaction(finalResult);
|
|
34
|
-
}
|
|
35
|
-
return finalResult;
|
|
36
|
-
});
|
|
37
|
-
} else if (tx.status === Status.Exclusive) {
|
|
38
|
-
return commitTransaction(finalResult);
|
|
39
|
-
}
|
|
40
|
-
return finalResult;
|
|
41
|
-
}
|
|
42
|
-
const handleTransactionError = (error) => {
|
|
43
|
-
if (commits) {
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
logger.error("Rolling back", tx.via, "due to error:", Diagnostic.weak(error?.message || `${error}`));
|
|
47
|
-
try {
|
|
48
|
-
const result = tx.rollback();
|
|
49
|
-
if (MaybePromise.is(result)) {
|
|
50
|
-
return Promise.resolve(result).catch((error2) => {
|
|
51
|
-
if (error2 !== error) {
|
|
52
|
-
logger.error("Secondary error in", tx.via, "rollback:", error2);
|
|
53
|
-
}
|
|
54
|
-
throw error;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
} catch (error2) {
|
|
58
|
-
if (error2 !== error) {
|
|
59
|
-
logger.error("Secondary error in", tx.via, "rollback:", error2);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
throw error;
|
|
63
|
-
};
|
|
64
|
-
const closeTransaction = tx.close.bind(tx);
|
|
65
|
-
let isAsync = false;
|
|
66
|
-
try {
|
|
67
|
-
const actorResult = actor(tx);
|
|
68
|
-
if (MaybePromise.is(actorResult)) {
|
|
69
|
-
isAsync = tx.isAsync = true;
|
|
70
|
-
return Promise.resolve(actorResult).then(commitTransaction, handleTransactionError).finally(closeTransaction);
|
|
71
|
-
}
|
|
72
|
-
const commitResult = commitTransaction(actorResult);
|
|
73
|
-
if (MaybePromise.is(commitResult)) {
|
|
74
|
-
isAsync = true;
|
|
75
|
-
return Promise.resolve(commitResult).catch(handleTransactionError).finally(closeTransaction);
|
|
76
|
-
}
|
|
77
|
-
return commitResult;
|
|
78
|
-
} catch (e) {
|
|
79
|
-
const result = handleTransactionError(e);
|
|
80
|
-
isAsync = true;
|
|
81
|
-
return Promise.resolve(result).finally(closeTransaction);
|
|
82
|
-
} finally {
|
|
83
|
-
if (!isAsync) {
|
|
84
|
-
tx.close();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
20
|
+
function open(via) {
|
|
21
|
+
return new Tx(via);
|
|
87
22
|
}
|
|
88
23
|
class Tx {
|
|
89
24
|
#participants = /* @__PURE__ */ new Set();
|
|
@@ -104,12 +39,9 @@ class Tx {
|
|
|
104
39
|
this.#status = Status.Shared;
|
|
105
40
|
}
|
|
106
41
|
}
|
|
107
|
-
|
|
108
|
-
|
|
42
|
+
[Symbol.dispose]() {
|
|
43
|
+
this.#reset("dropped");
|
|
109
44
|
this.#status = Status.Destroyed;
|
|
110
|
-
this.#resources.clear();
|
|
111
|
-
this.#roles.clear();
|
|
112
|
-
this.#participants.clear();
|
|
113
45
|
this.#closed?.emit();
|
|
114
46
|
}
|
|
115
47
|
get via() {
|
|
@@ -130,6 +62,9 @@ class Tx {
|
|
|
130
62
|
get isAsync() {
|
|
131
63
|
return this.#isAsync;
|
|
132
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* We set this during async processing. This enables the lock reporting when too much time ellapses.
|
|
67
|
+
*/
|
|
133
68
|
set isAsync(isAsync) {
|
|
134
69
|
if (!this.#isAsync) {
|
|
135
70
|
this.#locksChanged(this.#resources);
|
|
@@ -239,28 +174,97 @@ class Tx {
|
|
|
239
174
|
return this.#roles.get(role);
|
|
240
175
|
}
|
|
241
176
|
commit() {
|
|
242
|
-
this
|
|
243
|
-
if (this.#status === Status.Shared) {
|
|
177
|
+
if (this.status === Status.Shared) {
|
|
244
178
|
return this.rollback();
|
|
245
179
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const result = this.#executePreCommit();
|
|
180
|
+
this.#assertAvailable();
|
|
181
|
+
const result = this.#executeCommitCycle(0);
|
|
182
|
+
if (result) {
|
|
183
|
+
this.isAsync = true;
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
resolve(result) {
|
|
255
188
|
if (MaybePromise.is(result)) {
|
|
256
|
-
|
|
189
|
+
this.isAsync = true;
|
|
190
|
+
return result.then(this.resolve.bind(this), this.reject.bind(this));
|
|
191
|
+
}
|
|
192
|
+
let promise;
|
|
193
|
+
try {
|
|
194
|
+
promise = this.commit();
|
|
195
|
+
} catch (e) {
|
|
196
|
+
return this.reject(e);
|
|
257
197
|
}
|
|
258
|
-
|
|
198
|
+
if (MaybePromise.is(promise)) {
|
|
199
|
+
this.isAsync = true;
|
|
200
|
+
return Promise.resolve(promise).then(() => {
|
|
201
|
+
this[Symbol.dispose]();
|
|
202
|
+
return result;
|
|
203
|
+
}, this.reject.bind(this)).finally(this[Symbol.dispose].bind(this));
|
|
204
|
+
}
|
|
205
|
+
this[Symbol.dispose]();
|
|
206
|
+
return result;
|
|
259
207
|
}
|
|
260
208
|
rollback() {
|
|
261
209
|
this.#assertAvailable();
|
|
262
210
|
return this.#finalize(Status.RollingBack, "rolled back", () => this.#executeRollback());
|
|
263
211
|
}
|
|
212
|
+
reject(cause) {
|
|
213
|
+
if (this.#status === Status.Shared) {
|
|
214
|
+
this.#reset("released");
|
|
215
|
+
throw cause;
|
|
216
|
+
}
|
|
217
|
+
logger.error("Rolling back", this.via, "due to error:", Diagnostic.weak(asError(cause).message));
|
|
218
|
+
try {
|
|
219
|
+
const result = this.rollback();
|
|
220
|
+
if (MaybePromise.is(result)) {
|
|
221
|
+
return Promise.resolve(result).catch((cause2) => {
|
|
222
|
+
if (cause2 === cause) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
logger.error("Secondary error in", this.via, "rollback:", cause2);
|
|
226
|
+
}).finally(() => {
|
|
227
|
+
this[Symbol.dispose]();
|
|
228
|
+
throw cause;
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
} catch (cause2) {
|
|
232
|
+
if (cause2 !== cause) {
|
|
233
|
+
logger.error("Secondary error in", this.via, "rollback:", cause2);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
this[Symbol.dispose]();
|
|
237
|
+
throw cause;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Execute commit logic for a single commit cycle.
|
|
241
|
+
*
|
|
242
|
+
* A "cycle" performs all commit logic and normally brings us back to shared state. But we allow post-commit
|
|
243
|
+
* handlers to re-enter exclusive state. If that happens, we trigger another commit cycle.
|
|
244
|
+
*/
|
|
245
|
+
#executeCommitCycle(count) {
|
|
246
|
+
count++;
|
|
247
|
+
if (count > MAX_CHAINED_COMMITS) {
|
|
248
|
+
throw new TransactionFlowError(
|
|
249
|
+
`Transaction commits have cascaded ${count} times which likely indicates an infinite loop`
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
let result = this.#createPreCommitExecutor()();
|
|
253
|
+
if (MaybePromise.is(result)) {
|
|
254
|
+
result = result.then(this.#executeCommit.bind(this));
|
|
255
|
+
} else {
|
|
256
|
+
result = this.#executeCommit();
|
|
257
|
+
}
|
|
258
|
+
if (MaybePromise.is(result)) {
|
|
259
|
+
return result.then(() => {
|
|
260
|
+
if (this.#status === Status.Exclusive) {
|
|
261
|
+
return this.#executeCommitCycle(count);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
} else if (this.#status === Status.Exclusive) {
|
|
265
|
+
return this.#executeCommitCycle(count);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
264
268
|
waitFor(others) {
|
|
265
269
|
this.#assertAvailable();
|
|
266
270
|
if (this.waitingOn) {
|
|
@@ -306,34 +310,39 @@ class Tx {
|
|
|
306
310
|
`Illegal attempt to enter status ${status} when transaction is ${this.#status}`
|
|
307
311
|
);
|
|
308
312
|
}
|
|
309
|
-
const cleanup = () => {
|
|
310
|
-
const set = new ResourceSet(this, this.#resources);
|
|
311
|
-
const unlocked = set.releaseLocks();
|
|
312
|
-
this.#locksChanged(unlocked, `${why} and unlocked`);
|
|
313
|
-
Monitor.delete(this);
|
|
314
|
-
this.#reportingLocks = false;
|
|
315
|
-
this.#participants.clear();
|
|
316
|
-
this.#status = Status.Shared;
|
|
317
|
-
this.#shared?.emit();
|
|
318
|
-
};
|
|
319
313
|
let isAsync = false;
|
|
320
314
|
try {
|
|
321
315
|
this.#status = status;
|
|
322
316
|
const result = finalizer();
|
|
323
317
|
if (MaybePromise.is(result)) {
|
|
324
318
|
isAsync = true;
|
|
325
|
-
return Promise.resolve(result).finally(
|
|
319
|
+
return Promise.resolve(result).finally(() => this.#reset(why));
|
|
326
320
|
}
|
|
327
321
|
} finally {
|
|
328
322
|
if (!isAsync) {
|
|
329
|
-
|
|
323
|
+
this.#reset(why);
|
|
330
324
|
}
|
|
331
325
|
}
|
|
332
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Reset state to shared with no resources or participants.
|
|
329
|
+
*/
|
|
330
|
+
#reset(why) {
|
|
331
|
+
const set = new ResourceSet(this, this.#resources);
|
|
332
|
+
const unlocked = set.releaseLocks();
|
|
333
|
+
this.#locksChanged(unlocked, `${why} and unlocked`);
|
|
334
|
+
this.#resources.clear();
|
|
335
|
+
Monitor.delete(this);
|
|
336
|
+
this.#reportingLocks = false;
|
|
337
|
+
this.#participants.clear();
|
|
338
|
+
this.#roles.clear();
|
|
339
|
+
this.#status = Status.Shared;
|
|
340
|
+
this.#shared?.emit();
|
|
341
|
+
}
|
|
333
342
|
/**
|
|
334
343
|
* Iteratively execute pre-commit until all participants "settle" and report no possible mutation.
|
|
335
344
|
*/
|
|
336
|
-
#
|
|
345
|
+
#createPreCommitExecutor() {
|
|
337
346
|
let mayHaveMutated = false;
|
|
338
347
|
let abortedDueToError = false;
|
|
339
348
|
let iterator = this.participants[Symbol.iterator]();
|
|
@@ -365,7 +374,7 @@ class Tx {
|
|
|
365
374
|
mayHaveMutated = false;
|
|
366
375
|
iterator = this.participants[Symbol.iterator]();
|
|
367
376
|
};
|
|
368
|
-
const
|
|
377
|
+
const executePreCommit = (previousResult) => {
|
|
369
378
|
if (abortedDueToError) {
|
|
370
379
|
return;
|
|
371
380
|
}
|
|
@@ -392,7 +401,7 @@ class Tx {
|
|
|
392
401
|
try {
|
|
393
402
|
const result = participant.preCommit?.();
|
|
394
403
|
if (MaybePromise.is(result)) {
|
|
395
|
-
return Promise.resolve(result).catch(handleError).then(
|
|
404
|
+
return Promise.resolve(result).catch(handleError).then(executePreCommit);
|
|
396
405
|
}
|
|
397
406
|
if (result) {
|
|
398
407
|
mayHaveMutated = true;
|
|
@@ -402,17 +411,26 @@ class Tx {
|
|
|
402
411
|
}
|
|
403
412
|
}
|
|
404
413
|
};
|
|
405
|
-
return
|
|
414
|
+
return executePreCommit;
|
|
406
415
|
}
|
|
407
416
|
/**
|
|
408
|
-
*
|
|
417
|
+
* Handle actual commit and post-commit.
|
|
409
418
|
*/
|
|
410
419
|
#executeCommit() {
|
|
411
|
-
const
|
|
420
|
+
const participants = [...this.#participants];
|
|
421
|
+
const executeCommit = () => {
|
|
422
|
+
const result2 = this.#executeCommit1();
|
|
423
|
+
if (MaybePromise.is(result2)) {
|
|
424
|
+
return Promise.resolve(result2).then(this.#executeCommit2.bind(this));
|
|
425
|
+
}
|
|
426
|
+
return this.#executeCommit2();
|
|
427
|
+
};
|
|
428
|
+
const result = this.#finalize(Status.CommittingPhaseOne, "committed", executeCommit);
|
|
429
|
+
const executePostCommit = this.#createPostCommitExecutor(participants);
|
|
412
430
|
if (MaybePromise.is(result)) {
|
|
413
|
-
return
|
|
431
|
+
return result.then(executePostCommit);
|
|
414
432
|
}
|
|
415
|
-
return
|
|
433
|
+
return executePostCommit();
|
|
416
434
|
}
|
|
417
435
|
#executeCommit1() {
|
|
418
436
|
let needRollback = false;
|
|
@@ -482,23 +500,35 @@ class Tx {
|
|
|
482
500
|
throwIfErrored(errored, "in commit phase 2");
|
|
483
501
|
}
|
|
484
502
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
503
|
+
/**
|
|
504
|
+
* Execute post-commit phase.
|
|
505
|
+
*
|
|
506
|
+
* We notify each participant sequentially. If a participant throws, we log the error and move on to the next
|
|
507
|
+
* participant.
|
|
508
|
+
*/
|
|
509
|
+
#createPostCommitExecutor(participants) {
|
|
510
|
+
let i = 0;
|
|
511
|
+
const executePostCommit = () => {
|
|
512
|
+
for (; i < participants.length; i++) {
|
|
513
|
+
let reportParticipantError2 = function(e) {
|
|
514
|
+
logger.error(`Error post-commit of ${participant}:`, e);
|
|
515
|
+
};
|
|
516
|
+
var reportParticipantError = reportParticipantError2;
|
|
517
|
+
const participant = participants[i];
|
|
518
|
+
try {
|
|
519
|
+
const promise = participant.postCommit?.();
|
|
520
|
+
if (MaybePromise.is(promise)) {
|
|
521
|
+
return Promise.resolve(promise).then(executePostCommit, (e) => {
|
|
522
|
+
reportParticipantError2(e);
|
|
523
|
+
executePostCommit();
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
} catch (e) {
|
|
527
|
+
reportParticipantError2(e);
|
|
498
528
|
}
|
|
499
|
-
|
|
529
|
+
}
|
|
500
530
|
};
|
|
501
|
-
return
|
|
531
|
+
return executePostCommit;
|
|
502
532
|
}
|
|
503
533
|
/**
|
|
504
534
|
* Rollback logic passed to #finish.
|
|
@@ -622,6 +652,6 @@ const Monitor = /* @__PURE__ */ function() {
|
|
|
622
652
|
}();
|
|
623
653
|
export {
|
|
624
654
|
ReadOnlyTransaction,
|
|
625
|
-
|
|
655
|
+
open
|
|
626
656
|
};
|
|
627
657
|
//# sourceMappingURL=Tx.js.map
|