@dbos-inc/knex-datasource 3.0.7-preview → 3.0.8-preview
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/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -57
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +90 -71
- package/package.json +6 -5
- package/tests/config.test.ts +1 -1
- package/tests/datasource.test.ts +164 -41
- package/tests/test-helpers.ts +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { type Knex } from 'knex';
|
|
|
3
3
|
export type TransactionConfig = Pick<Knex.TransactionConfig, 'isolationLevel' | 'readOnly'>;
|
|
4
4
|
export declare class KnexDataSource implements DBOSDataSource<TransactionConfig> {
|
|
5
5
|
#private;
|
|
6
|
+
readonly name: string;
|
|
6
7
|
static get client(): Knex.Transaction;
|
|
7
8
|
static initializeInternalSchema(config: Knex.Config): Promise<void>;
|
|
8
|
-
readonly name: string;
|
|
9
9
|
constructor(name: string, config: Knex.Config);
|
|
10
10
|
runTransaction<T>(callback: () => Promise<T>, funcName: string, config?: TransactionConfig): Promise<T>;
|
|
11
|
-
registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>,
|
|
12
|
-
transaction(config?: TransactionConfig): <This, Args extends unknown[], Return>(_target: object, propertyKey:
|
|
11
|
+
registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>, config?: TransactionConfig, name?: string): (this: This, ...args: Args) => Promise<Return>;
|
|
12
|
+
transaction(config?: TransactionConfig): <This, Args extends unknown[], Return>(_target: object, propertyKey: PropertyKey, descriptor: TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>) => TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>;
|
|
13
13
|
}
|
|
14
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAGA,OAAO,EAML,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAGA,OAAO,EAML,cAAc,EAIf,MAAM,+BAA+B,CAAC;AAEvC,OAAa,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAcvC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,GAAG,UAAU,CAAC,CAAC;AA8J5F,qBAAa,cAAe,YAAW,cAAc,CAAC,iBAAiB,CAAC;;IAyBpE,QAAQ,CAAC,IAAI,EAAE,MAAM;IAxBvB,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CASpC;WAEY,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM;gBAa9C,IAAI,EAAE,MAAM,EACrB,MAAM,EAAE,IAAI,CAAC,MAAM;IAMf,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,iBAAiB;IAIhG,mBAAmB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EACpD,MAAM,CAAC,EAAE,iBAAiB,EAC1B,IAAI,CAAC,EAAE,MAAM,GACZ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD,WAAW,CAAC,MAAM,CAAC,EAAE,iBAAiB,mDAIzB,MAAM,eACF,WAAW,cACZ,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,oCAAxC,IAAI,WAAW,IAAI,KAAK,QAAQ,MAAM,CAAC;CAWvF"}
|
package/dist/index.js
CHANGED
|
@@ -11,36 +11,68 @@ const async_hooks_1 = require("async_hooks");
|
|
|
11
11
|
const knex_1 = __importDefault(require("knex"));
|
|
12
12
|
const superjson_1 = require("superjson");
|
|
13
13
|
const asyncLocalCtx = new async_hooks_1.AsyncLocalStorage();
|
|
14
|
-
class
|
|
14
|
+
class KnexTransactionHandler {
|
|
15
15
|
name;
|
|
16
|
+
config;
|
|
16
17
|
dsType = 'KnexDataSource';
|
|
17
|
-
#
|
|
18
|
+
#knexDBField;
|
|
18
19
|
constructor(name, config) {
|
|
19
20
|
this.name = name;
|
|
20
|
-
this
|
|
21
|
+
this.config = config;
|
|
21
22
|
}
|
|
22
|
-
initialize() {
|
|
23
|
-
|
|
23
|
+
async initialize() {
|
|
24
|
+
const knexDB = this.#knexDBField;
|
|
25
|
+
this.#knexDBField = (0, knex_1.default)(this.config);
|
|
26
|
+
await knexDB?.destroy();
|
|
24
27
|
}
|
|
25
|
-
destroy() {
|
|
26
|
-
|
|
28
|
+
async destroy() {
|
|
29
|
+
const knexDB = this.#knexDBField;
|
|
30
|
+
this.#knexDBField = undefined;
|
|
31
|
+
await knexDB?.destroy();
|
|
27
32
|
}
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
get #knexDB() {
|
|
34
|
+
if (!this.#knexDBField) {
|
|
35
|
+
throw new Error(`DataSource ${this.name} is not initialized.`);
|
|
36
|
+
}
|
|
37
|
+
return this.#knexDBField;
|
|
38
|
+
}
|
|
39
|
+
async #checkExecution(workflowID, stepID) {
|
|
40
|
+
const result = await this.#knexDB('transaction_completion')
|
|
30
41
|
.withSchema('dbos')
|
|
31
|
-
.select('output')
|
|
42
|
+
.select('output', 'error')
|
|
32
43
|
.where({
|
|
33
44
|
workflow_id: workflowID,
|
|
34
|
-
function_num:
|
|
45
|
+
function_num: stepID,
|
|
35
46
|
})
|
|
36
47
|
.first();
|
|
37
|
-
|
|
48
|
+
if (result === undefined) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const { output, error } = result;
|
|
52
|
+
return error !== null ? { error } : { output };
|
|
38
53
|
}
|
|
39
|
-
|
|
54
|
+
async #recordError(workflowID, stepID, error) {
|
|
55
|
+
try {
|
|
56
|
+
await this.#knexDB('transaction_completion').withSchema('dbos').insert({
|
|
57
|
+
workflow_id: workflowID,
|
|
58
|
+
function_num: stepID,
|
|
59
|
+
error,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if ((0, datasource_1.isPGKeyConflictError)(error)) {
|
|
64
|
+
throw new dbos_sdk_1.DBOSWorkflowConflictError(workflowID);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
static async #recordOutput(client, workflowID, stepID, output) {
|
|
40
72
|
try {
|
|
41
73
|
await client('transaction_completion').withSchema('dbos').insert({
|
|
42
74
|
workflow_id: workflowID,
|
|
43
|
-
function_num:
|
|
75
|
+
function_num: stepID,
|
|
44
76
|
output,
|
|
45
77
|
});
|
|
46
78
|
}
|
|
@@ -55,57 +87,52 @@ class KnexDSTH {
|
|
|
55
87
|
}
|
|
56
88
|
async invokeTransactionFunction(config, target, func, ...args) {
|
|
57
89
|
const workflowID = dbos_sdk_1.DBOS.workflowID;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const functionNum = dbos_sdk_1.DBOS.stepID;
|
|
62
|
-
if (functionNum === undefined) {
|
|
63
|
-
throw new Error('Function Number is not set.');
|
|
90
|
+
const stepID = dbos_sdk_1.DBOS.stepID;
|
|
91
|
+
if (workflowID !== undefined && stepID === undefined) {
|
|
92
|
+
throw new Error('DBOS.stepID is undefined inside a workflow.');
|
|
64
93
|
}
|
|
65
94
|
const readOnly = config?.readOnly ?? false;
|
|
95
|
+
const saveResults = !readOnly && workflowID !== undefined;
|
|
96
|
+
// Retry loop if appropriate
|
|
66
97
|
let retryWaitMS = 1;
|
|
67
98
|
const backoffFactor = 1.5;
|
|
68
|
-
const maxRetryWaitMS = 2000;
|
|
99
|
+
const maxRetryWaitMS = 2000; // Maximum wait 2 seconds.
|
|
69
100
|
while (true) {
|
|
101
|
+
// Check to see if this tx has already been executed
|
|
102
|
+
const previousResult = saveResults ? await this.#checkExecution(workflowID, stepID) : undefined;
|
|
103
|
+
if (previousResult) {
|
|
104
|
+
dbos_sdk_1.DBOS.span?.setAttribute('cached', true);
|
|
105
|
+
if ('error' in previousResult) {
|
|
106
|
+
throw superjson_1.SuperJSON.parse(previousResult.error);
|
|
107
|
+
}
|
|
108
|
+
return (previousResult.output ? superjson_1.SuperJSON.parse(previousResult.output) : null);
|
|
109
|
+
}
|
|
70
110
|
try {
|
|
71
111
|
const result = await this.#knexDB.transaction(async (client) => {
|
|
72
|
-
// Check to see if this tx has already been executed
|
|
73
|
-
const previousResult = readOnly || !workflowID ? undefined : await KnexDSTH.#checkExecution(client, workflowID, functionNum);
|
|
74
|
-
if (previousResult) {
|
|
75
|
-
return (previousResult.output ? superjson_1.SuperJSON.parse(previousResult.output) : null);
|
|
76
|
-
}
|
|
77
112
|
// execute user's transaction function
|
|
78
113
|
const result = await asyncLocalCtx.run({ client }, async () => {
|
|
79
114
|
return (await func.call(target, ...args));
|
|
80
115
|
});
|
|
81
116
|
// save the output of read/write transactions
|
|
82
|
-
if (
|
|
83
|
-
await
|
|
84
|
-
// Note, existing code wraps #recordOutput call in a try/catch block that
|
|
85
|
-
// converts DB error with code 25P02 to DBOSFailedSqlTransactionError.
|
|
86
|
-
// However, existing code doesn't make any logic decisions based on that error type.
|
|
87
|
-
// DBOSFailedSqlTransactionError does stored WF ID and function name, so I assume that info is logged out somewhere
|
|
117
|
+
if (saveResults) {
|
|
118
|
+
await KnexTransactionHandler.#recordOutput(client, workflowID, stepID, superjson_1.SuperJSON.stringify(result));
|
|
88
119
|
}
|
|
89
120
|
return result;
|
|
90
121
|
}, { isolationLevel: config?.isolationLevel, readOnly: config?.readOnly });
|
|
91
|
-
// TODO: span.setStatus({ code: SpanStatusCode.OK });
|
|
92
|
-
// TODO: this.tracer.endSpan(span);
|
|
93
122
|
return result;
|
|
94
123
|
}
|
|
95
124
|
catch (error) {
|
|
96
125
|
if ((0, datasource_1.isPGRetriableTransactionError)(error)) {
|
|
97
|
-
|
|
126
|
+
dbos_sdk_1.DBOS.span?.addEvent('TXN SERIALIZATION FAILURE', { retryWaitMillis: retryWaitMS }, performance.now());
|
|
98
127
|
await new Promise((resolve) => setTimeout(resolve, retryWaitMS));
|
|
99
128
|
retryWaitMS = Math.min(retryWaitMS * backoffFactor, maxRetryWaitMS);
|
|
100
129
|
continue;
|
|
101
130
|
}
|
|
102
131
|
else {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// However, I'm concerned that we have a dueling execution hole where one tx fails while another succeeds.
|
|
108
|
-
// This implies that we can end up in a situation where the step output records an error but the txOutput table records success.
|
|
132
|
+
if (saveResults) {
|
|
133
|
+
const message = superjson_1.SuperJSON.stringify(error);
|
|
134
|
+
await this.#recordError(workflowID, stepID, message);
|
|
135
|
+
}
|
|
109
136
|
throw error;
|
|
110
137
|
}
|
|
111
138
|
}
|
|
@@ -113,46 +140,38 @@ class KnexDSTH {
|
|
|
113
140
|
}
|
|
114
141
|
}
|
|
115
142
|
class KnexDataSource {
|
|
143
|
+
name;
|
|
116
144
|
static get client() {
|
|
117
145
|
if (!dbos_sdk_1.DBOS.isInTransaction()) {
|
|
118
146
|
throw new Error('invalid use of KnexDataSource.client outside of a DBOS transaction.');
|
|
119
147
|
}
|
|
120
148
|
const ctx = asyncLocalCtx.getStore();
|
|
121
149
|
if (!ctx) {
|
|
122
|
-
throw new Error('
|
|
150
|
+
throw new Error('invalid use of KnexDataSource.client outside of a DBOS transaction.');
|
|
123
151
|
}
|
|
124
152
|
return ctx.client;
|
|
125
153
|
}
|
|
126
154
|
static async initializeInternalSchema(config) {
|
|
127
155
|
const knexDB = (0, knex_1.default)(config);
|
|
128
156
|
try {
|
|
129
|
-
await knexDB.
|
|
130
|
-
|
|
131
|
-
if (!exists) {
|
|
132
|
-
await knexDB.schema.withSchema('dbos').createTable('transaction_completion', (table) => {
|
|
133
|
-
table.string('workflow_id').notNullable();
|
|
134
|
-
table.integer('function_num').notNullable();
|
|
135
|
-
table.string('output').nullable();
|
|
136
|
-
table.primary(['workflow_id', 'function_num']);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
157
|
+
await knexDB.raw(datasource_1.createTransactionCompletionSchemaPG);
|
|
158
|
+
await knexDB.raw(datasource_1.createTransactionCompletionTablePG);
|
|
139
159
|
}
|
|
140
160
|
finally {
|
|
141
161
|
await knexDB.destroy();
|
|
142
162
|
}
|
|
143
163
|
}
|
|
144
|
-
name;
|
|
145
164
|
#provider;
|
|
146
165
|
constructor(name, config) {
|
|
147
166
|
this.name = name;
|
|
148
|
-
this.#provider = new
|
|
167
|
+
this.#provider = new KnexTransactionHandler(name, config);
|
|
149
168
|
(0, datasource_1.registerDataSource)(this.#provider);
|
|
150
169
|
}
|
|
151
170
|
async runTransaction(callback, funcName, config) {
|
|
152
171
|
return await (0, datasource_1.runTransaction)(callback, funcName, { dsName: this.name, config });
|
|
153
172
|
}
|
|
154
|
-
registerTransaction(func,
|
|
155
|
-
return (0, datasource_1.registerTransaction)(this.name, func, { name }, config);
|
|
173
|
+
registerTransaction(func, config, name) {
|
|
174
|
+
return (0, datasource_1.registerTransaction)(this.name, func, { name: name ?? func.name }, config);
|
|
156
175
|
}
|
|
157
176
|
transaction(config) {
|
|
158
177
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
@@ -161,7 +180,7 @@ class KnexDataSource {
|
|
|
161
180
|
if (!descriptor.value) {
|
|
162
181
|
throw Error('Use of decorator when original method is undefined');
|
|
163
182
|
}
|
|
164
|
-
descriptor.value = ds.registerTransaction(descriptor.value,
|
|
183
|
+
descriptor.value = ds.registerTransaction(descriptor.value, config, String(propertyKey));
|
|
165
184
|
return descriptor;
|
|
166
185
|
};
|
|
167
186
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA,qCAAqC;;;;;;AAErC,iDAAqE;AACrE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|