@dbos-inc/knex-datasource 3.0.10-preview → 3.0.11-preview.gc9233b8190
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 +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -108
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +75 -123
- package/package.json +5 -6
- package/tests/config.test.ts +7 -47
- package/tests/datasource.test.ts +42 -165
- package/tests/test-helpers.ts +2 -3
package/dist/index.d.ts
CHANGED
|
@@ -3,13 +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;
|
|
7
6
|
static get client(): Knex.Transaction;
|
|
8
|
-
static
|
|
9
|
-
|
|
7
|
+
static initializeInternalSchema(config: Knex.Config): Promise<void>;
|
|
8
|
+
readonly name: string;
|
|
10
9
|
constructor(name: string, config: Knex.Config);
|
|
11
10
|
runTransaction<T>(callback: () => Promise<T>, funcName: string, config?: TransactionConfig): Promise<T>;
|
|
12
|
-
registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>,
|
|
13
|
-
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>, name: string, config?: TransactionConfig): (this: This, ...args: Args) => Promise<Return>;
|
|
12
|
+
transaction(config?: TransactionConfig): <This, Args extends unknown[], Return>(_target: object, propertyKey: string, descriptor: TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>) => TypedPropertyDescriptor<(this: This, ...args: Args) => Promise<Return>>;
|
|
14
13
|
}
|
|
15
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,EAEf,MAAM,+BAA+B,CAAC;AAEvC,OAAa,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAavC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,GAAG,UAAU,CAAC,CAAC;AAuI5F,qBAAa,cAAe,YAAW,cAAc,CAAC,iBAAiB,CAAC;;IACtE,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CASpC;WAEY,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM;IAkBzD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGV,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM;IAMvC,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,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,iBAAiB,GACzB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD,WAAW,CAAC,MAAM,CAAC,EAAE,iBAAiB,mDAIzB,MAAM,eACF,MAAM,cACP,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,68 +11,36 @@ 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 KnexDSTH {
|
|
15
15
|
name;
|
|
16
|
-
config;
|
|
17
16
|
dsType = 'KnexDataSource';
|
|
18
|
-
#
|
|
17
|
+
#knexDB;
|
|
19
18
|
constructor(name, config) {
|
|
20
19
|
this.name = name;
|
|
21
|
-
this
|
|
20
|
+
this.#knexDB = (0, knex_1.default)(config);
|
|
22
21
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.#knexDBField = (0, knex_1.default)(this.config);
|
|
26
|
-
await knexDB?.destroy();
|
|
22
|
+
initialize() {
|
|
23
|
+
return Promise.resolve();
|
|
27
24
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.#knexDBField = undefined;
|
|
31
|
-
await knexDB?.destroy();
|
|
25
|
+
destroy() {
|
|
26
|
+
return this.#knexDB.destroy();
|
|
32
27
|
}
|
|
33
|
-
|
|
34
|
-
|
|
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')
|
|
28
|
+
static async #checkExecution(client, workflowID, functionNum) {
|
|
29
|
+
const result = await client('transaction_completion')
|
|
41
30
|
.withSchema('dbos')
|
|
42
|
-
.select('output'
|
|
31
|
+
.select('output')
|
|
43
32
|
.where({
|
|
44
33
|
workflow_id: workflowID,
|
|
45
|
-
function_num:
|
|
34
|
+
function_num: functionNum,
|
|
46
35
|
})
|
|
47
36
|
.first();
|
|
48
|
-
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
51
|
-
const { output, error } = result;
|
|
52
|
-
return error !== null ? { error } : { output };
|
|
53
|
-
}
|
|
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
|
-
}
|
|
37
|
+
return result === undefined ? undefined : { output: result.output };
|
|
70
38
|
}
|
|
71
|
-
static async #recordOutput(client, workflowID,
|
|
39
|
+
static async #recordOutput(client, workflowID, functionNum, output) {
|
|
72
40
|
try {
|
|
73
41
|
await client('transaction_completion').withSchema('dbos').insert({
|
|
74
42
|
workflow_id: workflowID,
|
|
75
|
-
function_num:
|
|
43
|
+
function_num: functionNum,
|
|
76
44
|
output,
|
|
77
45
|
});
|
|
78
46
|
}
|
|
@@ -87,119 +55,104 @@ class KnexTransactionHandler {
|
|
|
87
55
|
}
|
|
88
56
|
async invokeTransactionFunction(config, target, func, ...args) {
|
|
89
57
|
const workflowID = dbos_sdk_1.DBOS.workflowID;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
58
|
+
if (workflowID === undefined) {
|
|
59
|
+
throw new Error('Workflow ID is not set.');
|
|
60
|
+
}
|
|
61
|
+
const functionNum = dbos_sdk_1.DBOS.stepID;
|
|
62
|
+
if (functionNum === undefined) {
|
|
63
|
+
throw new Error('Function Number is not set.');
|
|
93
64
|
}
|
|
94
65
|
const readOnly = config?.readOnly ?? false;
|
|
95
|
-
const saveResults = !readOnly && workflowID !== undefined;
|
|
96
|
-
// Retry loop if appropriate
|
|
97
66
|
let retryWaitMS = 1;
|
|
98
67
|
const backoffFactor = 1.5;
|
|
99
|
-
const maxRetryWaitMS = 2000;
|
|
68
|
+
const maxRetryWaitMS = 2000;
|
|
100
69
|
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
|
-
}
|
|
110
70
|
try {
|
|
111
71
|
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
|
+
}
|
|
112
77
|
// execute user's transaction function
|
|
113
78
|
const result = await asyncLocalCtx.run({ client }, async () => {
|
|
114
79
|
return (await func.call(target, ...args));
|
|
115
80
|
});
|
|
116
81
|
// save the output of read/write transactions
|
|
117
|
-
if (
|
|
118
|
-
await
|
|
82
|
+
if (!readOnly && workflowID) {
|
|
83
|
+
await KnexDSTH.#recordOutput(client, workflowID, functionNum, superjson_1.SuperJSON.stringify(result));
|
|
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
|
|
119
88
|
}
|
|
120
89
|
return result;
|
|
121
90
|
}, { isolationLevel: config?.isolationLevel, readOnly: config?.readOnly });
|
|
91
|
+
// TODO: span.setStatus({ code: SpanStatusCode.OK });
|
|
92
|
+
// TODO: this.tracer.endSpan(span);
|
|
122
93
|
return result;
|
|
123
94
|
}
|
|
124
95
|
catch (error) {
|
|
125
96
|
if ((0, datasource_1.isPGRetriableTransactionError)(error)) {
|
|
126
|
-
|
|
97
|
+
// TODO: span.addEvent('TXN SERIALIZATION FAILURE', { retryWaitMillis: retryWaitMillis }, performance.now());
|
|
127
98
|
await new Promise((resolve) => setTimeout(resolve, retryWaitMS));
|
|
128
99
|
retryWaitMS = Math.min(retryWaitMS * backoffFactor, maxRetryWaitMS);
|
|
129
100
|
continue;
|
|
130
101
|
}
|
|
131
102
|
else {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
103
|
+
// TODO: span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
|
|
104
|
+
// TODO: this.tracer.endSpan(span);
|
|
105
|
+
// TODO: currently, we are *not* recording errors in the txOutput table.
|
|
106
|
+
// For normal execution, this is fine because we also store tx step results (output and error) in the sysdb operation output table.
|
|
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.
|
|
136
109
|
throw error;
|
|
137
110
|
}
|
|
138
111
|
}
|
|
139
112
|
}
|
|
140
113
|
}
|
|
141
114
|
}
|
|
142
|
-
function isKnex(value) {
|
|
143
|
-
return 'raw' in value;
|
|
144
|
-
}
|
|
145
115
|
class KnexDataSource {
|
|
146
|
-
name;
|
|
147
116
|
static get client() {
|
|
148
117
|
if (!dbos_sdk_1.DBOS.isInTransaction()) {
|
|
149
118
|
throw new Error('invalid use of KnexDataSource.client outside of a DBOS transaction.');
|
|
150
119
|
}
|
|
151
120
|
const ctx = asyncLocalCtx.getStore();
|
|
152
121
|
if (!ctx) {
|
|
153
|
-
throw new Error('
|
|
122
|
+
throw new Error('No async local context found.');
|
|
154
123
|
}
|
|
155
124
|
return ctx.client;
|
|
156
125
|
}
|
|
157
|
-
static async
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
async function $initSchema(knexDB) {
|
|
171
|
-
await knexDB.raw(datasource_1.createTransactionCompletionSchemaPG);
|
|
172
|
-
await knexDB.raw(datasource_1.createTransactionCompletionTablePG);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
static async uninitializeSchema(knexOrConfig) {
|
|
176
|
-
if (isKnex(knexOrConfig)) {
|
|
177
|
-
await $uninitSchema(knexOrConfig);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
const knexDB = (0, knex_1.default)(knexOrConfig);
|
|
181
|
-
try {
|
|
182
|
-
await $uninitSchema(knexDB);
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
await knexDB.destroy();
|
|
126
|
+
static async initializeInternalSchema(config) {
|
|
127
|
+
const knexDB = (0, knex_1.default)(config);
|
|
128
|
+
try {
|
|
129
|
+
await knexDB.schema.createSchemaIfNotExists('dbos');
|
|
130
|
+
const exists = await knexDB.schema.withSchema('dbos').hasTable('transaction_completion');
|
|
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
|
+
});
|
|
186
138
|
}
|
|
187
139
|
}
|
|
188
|
-
|
|
189
|
-
await knexDB.
|
|
140
|
+
finally {
|
|
141
|
+
await knexDB.destroy();
|
|
190
142
|
}
|
|
191
143
|
}
|
|
144
|
+
name;
|
|
192
145
|
#provider;
|
|
193
146
|
constructor(name, config) {
|
|
194
147
|
this.name = name;
|
|
195
|
-
this.#provider = new
|
|
148
|
+
this.#provider = new KnexDSTH(name, config);
|
|
196
149
|
(0, datasource_1.registerDataSource)(this.#provider);
|
|
197
150
|
}
|
|
198
151
|
async runTransaction(callback, funcName, config) {
|
|
199
152
|
return await (0, datasource_1.runTransaction)(callback, funcName, { dsName: this.name, config });
|
|
200
153
|
}
|
|
201
|
-
registerTransaction(func,
|
|
202
|
-
return (0, datasource_1.registerTransaction)(this.name, func, { name
|
|
154
|
+
registerTransaction(func, name, config) {
|
|
155
|
+
return (0, datasource_1.registerTransaction)(this.name, func, { name }, config);
|
|
203
156
|
}
|
|
204
157
|
transaction(config) {
|
|
205
158
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
@@ -208,7 +161,7 @@ class KnexDataSource {
|
|
|
208
161
|
if (!descriptor.value) {
|
|
209
162
|
throw Error('Use of decorator when original method is undefined');
|
|
210
163
|
}
|
|
211
|
-
descriptor.value = ds.registerTransaction(descriptor.value,
|
|
164
|
+
descriptor.value = ds.registerTransaction(descriptor.value, propertyKey.toString(), config);
|
|
212
165
|
return descriptor;
|
|
213
166
|
};
|
|
214
167
|
}
|
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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"}
|