@dbos-inc/node-pg-datasource 3.0.8-preview → 3.0.8-preview.g493d2d1c2b
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 +48 -75
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/index.ts +75 -105
- package/package.json +5 -6
- package/tests/config.test.ts +1 -1
- package/tests/datasource.test.ts +58 -179
- package/tests/test-helpers.ts +2 -3
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { type ClientBase, type ClientConfig, type PoolConfig } from 'pg';
|
|
|
3
3
|
export { NodePostgresTransactionOptions };
|
|
4
4
|
export declare class NodePostgresDataSource implements DBOSDataSource<NodePostgresTransactionOptions> {
|
|
5
5
|
#private;
|
|
6
|
-
readonly name: string;
|
|
7
6
|
static get client(): ClientBase;
|
|
8
7
|
static initializeInternalSchema(config: ClientConfig): Promise<void>;
|
|
8
|
+
readonly name: string;
|
|
9
9
|
constructor(name: string, config: PoolConfig);
|
|
10
10
|
runTransaction<T>(callback: () => Promise<T>, funcName: string, config?: NodePostgresTransactionOptions): Promise<T>;
|
|
11
|
-
registerTransaction<This, Args extends unknown[], Return>(func: (this: This, ...args: Args) => Promise<Return>,
|
|
12
|
-
transaction(config?: NodePostgresTransactionOptions): <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?: NodePostgresTransactionOptions): (this: This, ...args: Args) => Promise<Return>;
|
|
12
|
+
transaction(config?: NodePostgresTransactionOptions): <This, Args extends unknown[], Return>(_target: object, propertyKey: string, 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,EAQL,mBAAmB,IAAI,8BAA8B,EACrD,cAAc,EAEf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAU,KAAK,UAAU,EAAE,KAAK,YAAY,EAAQ,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAQvF,OAAO,EAAE,8BAA8B,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAGA,OAAO,EAQL,mBAAmB,IAAI,8BAA8B,EACrD,cAAc,EAEf,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAU,KAAK,UAAU,EAAE,KAAK,YAAY,EAAQ,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAQvF,OAAO,EAAE,8BAA8B,EAAE,CAAC;AA2J1C,qBAAa,sBAAuB,YAAW,cAAc,CAAC,8BAA8B,CAAC;;IAC3F,MAAM,KAAK,MAAM,IAAI,UAAU,CAS9B;WAEY,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGV,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;IAMtC,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,8BAA8B;IAI7G,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,8BAA8B,GACtC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD,WAAW,CAAC,MAAM,CAAC,EAAE,8BAA8B,mDAItC,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
|
@@ -8,64 +8,32 @@ const pg_1 = require("pg");
|
|
|
8
8
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
9
9
|
const superjson_1 = require("superjson");
|
|
10
10
|
const asyncLocalCtx = new node_async_hooks_1.AsyncLocalStorage();
|
|
11
|
-
class
|
|
11
|
+
class NodePGDSTH {
|
|
12
12
|
name;
|
|
13
|
-
config;
|
|
14
13
|
dsType = 'NodePostgresDataSource';
|
|
15
|
-
#
|
|
14
|
+
#pool;
|
|
16
15
|
constructor(name, config) {
|
|
17
16
|
this.name = name;
|
|
18
|
-
this
|
|
17
|
+
this.#pool = new pg_1.Pool(config);
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.#poolField = new pg_1.Pool(this.config);
|
|
23
|
-
await pool?.end();
|
|
19
|
+
initialize() {
|
|
20
|
+
return Promise.resolve();
|
|
24
21
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.#poolField = undefined;
|
|
28
|
-
await pool?.end();
|
|
22
|
+
destroy() {
|
|
23
|
+
return this.#pool.end();
|
|
29
24
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
async #checkExecution(workflowID, stepID) {
|
|
37
|
-
const { rows } = await this.#pool.query(
|
|
38
|
-
/*sql*/
|
|
39
|
-
`SELECT output, error FROM dbos.transaction_completion
|
|
40
|
-
WHERE workflow_id = $1 AND function_num = $2`, [workflowID, stepID]);
|
|
41
|
-
if (rows.length === 0) {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
const { output, error } = rows[0];
|
|
45
|
-
return error !== null ? { error } : { output };
|
|
25
|
+
static async #checkExecution(client, workflowID, functionNum) {
|
|
26
|
+
const { rows } = await client.query(
|
|
27
|
+
/*sql*/ `SELECT output FROM dbos.transaction_completion
|
|
28
|
+
WHERE workflow_id = $1 AND function_num = $2`, [workflowID, functionNum]);
|
|
29
|
+
return rows.length > 0 ? { output: rows[0].output } : undefined;
|
|
46
30
|
}
|
|
47
|
-
static async #recordOutput(client, workflowID,
|
|
31
|
+
static async #recordOutput(client, workflowID, functionNum, output) {
|
|
48
32
|
try {
|
|
49
33
|
await client.query(
|
|
50
34
|
/*sql*/
|
|
51
35
|
`INSERT INTO dbos.transaction_completion (workflow_id, function_num, output)
|
|
52
|
-
VALUES ($1, $2, $3)`, [workflowID,
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
if ((0, datasource_1.isPGKeyConflictError)(error)) {
|
|
56
|
-
throw new dbos_sdk_1.DBOSWorkflowConflictError(workflowID);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
throw error;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
async #recordError(workflowID, stepID, error) {
|
|
64
|
-
try {
|
|
65
|
-
await this.#pool.query(
|
|
66
|
-
/*sql*/
|
|
67
|
-
`INSERT INTO dbos.transaction_completion (workflow_id, function_num, error)
|
|
68
|
-
VALUES ($1, $2, $3)`, [workflowID, stepID, error]);
|
|
36
|
+
VALUES ($1, $2, $3)`, [workflowID, functionNum, output]);
|
|
69
37
|
}
|
|
70
38
|
catch (error) {
|
|
71
39
|
if ((0, datasource_1.isPGKeyConflictError)(error)) {
|
|
@@ -97,52 +65,57 @@ class NodePostgresTransactionHandler {
|
|
|
97
65
|
}
|
|
98
66
|
async invokeTransactionFunction(config, target, func, ...args) {
|
|
99
67
|
const workflowID = dbos_sdk_1.DBOS.workflowID;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
68
|
+
if (workflowID === undefined) {
|
|
69
|
+
throw new Error('Workflow ID is not set.');
|
|
70
|
+
}
|
|
71
|
+
const functionNum = dbos_sdk_1.DBOS.stepID;
|
|
72
|
+
if (functionNum === undefined) {
|
|
73
|
+
throw new Error('Function Number is not set.');
|
|
103
74
|
}
|
|
104
75
|
const readOnly = config?.readOnly ?? false;
|
|
105
|
-
const saveResults = !readOnly && workflowID !== undefined;
|
|
106
|
-
// Retry loop if appropriate
|
|
107
76
|
let retryWaitMS = 1;
|
|
108
77
|
const backoffFactor = 1.5;
|
|
109
|
-
const maxRetryWaitMS = 2000;
|
|
78
|
+
const maxRetryWaitMS = 2000;
|
|
110
79
|
while (true) {
|
|
111
|
-
// Check to see if this tx has already been executed
|
|
112
|
-
const previousResult = saveResults ? await this.#checkExecution(workflowID, stepID) : undefined;
|
|
113
|
-
if (previousResult) {
|
|
114
|
-
dbos_sdk_1.DBOS.span?.setAttribute('cached', true);
|
|
115
|
-
if ('error' in previousResult) {
|
|
116
|
-
throw superjson_1.SuperJSON.parse(previousResult.error);
|
|
117
|
-
}
|
|
118
|
-
return (previousResult.output ? superjson_1.SuperJSON.parse(previousResult.output) : null);
|
|
119
|
-
}
|
|
120
80
|
try {
|
|
121
81
|
const result = await this.#transaction(async (client) => {
|
|
82
|
+
// Check to see if this tx has already been executed
|
|
83
|
+
const previousResult = readOnly || !workflowID ? undefined : await NodePGDSTH.#checkExecution(client, workflowID, functionNum);
|
|
84
|
+
if (previousResult) {
|
|
85
|
+
return (previousResult.output ? superjson_1.SuperJSON.parse(previousResult.output) : null);
|
|
86
|
+
}
|
|
122
87
|
// execute user's transaction function
|
|
123
88
|
const result = await asyncLocalCtx.run({ client }, async () => {
|
|
124
89
|
return (await func.call(target, ...args));
|
|
125
90
|
});
|
|
126
91
|
// save the output of read/write transactions
|
|
127
|
-
if (
|
|
128
|
-
await
|
|
92
|
+
if (!readOnly && workflowID) {
|
|
93
|
+
await NodePGDSTH.#recordOutput(client, workflowID, functionNum, superjson_1.SuperJSON.stringify(result));
|
|
94
|
+
// Note, existing code wraps #recordOutput call in a try/catch block that
|
|
95
|
+
// converts DB error with code 25P02 to DBOSFailedSqlTransactionError.
|
|
96
|
+
// However, existing code doesn't make any logic decisions based on that error type.
|
|
97
|
+
// DBOSFailedSqlTransactionError does stored WF ID and function name, so I assume that info is logged out somewhere
|
|
129
98
|
}
|
|
130
99
|
return result;
|
|
131
|
-
}, config);
|
|
100
|
+
}, { isolationLevel: config?.isolationLevel, readOnly: config?.readOnly });
|
|
101
|
+
// TODO: span.setStatus({ code: SpanStatusCode.OK });
|
|
102
|
+
// TODO: this.tracer.endSpan(span);
|
|
132
103
|
return result;
|
|
133
104
|
}
|
|
134
105
|
catch (error) {
|
|
135
106
|
if ((0, datasource_1.isPGRetriableTransactionError)(error)) {
|
|
136
|
-
|
|
107
|
+
// TODO: span.addEvent('TXN SERIALIZATION FAILURE', { retryWaitMillis: retryWaitMillis }, performance.now());
|
|
137
108
|
await new Promise((resolve) => setTimeout(resolve, retryWaitMS));
|
|
138
109
|
retryWaitMS = Math.min(retryWaitMS * backoffFactor, maxRetryWaitMS);
|
|
139
110
|
continue;
|
|
140
111
|
}
|
|
141
112
|
else {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
113
|
+
// TODO: span.setStatus({ code: SpanStatusCode.ERROR, message: e.message });
|
|
114
|
+
// TODO: this.tracer.endSpan(span);
|
|
115
|
+
// TODO: currently, we are *not* recording errors in the txOutput table.
|
|
116
|
+
// For normal execution, this is fine because we also store tx step results (output and error) in the sysdb operation output table.
|
|
117
|
+
// However, I'm concerned that we have a dueling execution hole where one tx fails while another succeeds.
|
|
118
|
+
// This implies that we can end up in a situation where the step output records an error but the txOutput table records success.
|
|
146
119
|
throw error;
|
|
147
120
|
}
|
|
148
121
|
}
|
|
@@ -150,14 +123,13 @@ class NodePostgresTransactionHandler {
|
|
|
150
123
|
}
|
|
151
124
|
}
|
|
152
125
|
class NodePostgresDataSource {
|
|
153
|
-
name;
|
|
154
126
|
static get client() {
|
|
155
127
|
if (!dbos_sdk_1.DBOS.isInTransaction()) {
|
|
156
128
|
throw new Error('invalid use of NodePostgresDataSource.client outside of a DBOS transaction.');
|
|
157
129
|
}
|
|
158
130
|
const ctx = asyncLocalCtx.getStore();
|
|
159
131
|
if (!ctx) {
|
|
160
|
-
throw new Error('
|
|
132
|
+
throw new Error('No async local context found.');
|
|
161
133
|
}
|
|
162
134
|
return ctx.client;
|
|
163
135
|
}
|
|
@@ -172,17 +144,18 @@ class NodePostgresDataSource {
|
|
|
172
144
|
await client.end();
|
|
173
145
|
}
|
|
174
146
|
}
|
|
147
|
+
name;
|
|
175
148
|
#provider;
|
|
176
149
|
constructor(name, config) {
|
|
177
150
|
this.name = name;
|
|
178
|
-
this.#provider = new
|
|
151
|
+
this.#provider = new NodePGDSTH(name, config);
|
|
179
152
|
(0, datasource_1.registerDataSource)(this.#provider);
|
|
180
153
|
}
|
|
181
154
|
async runTransaction(callback, funcName, config) {
|
|
182
155
|
return await (0, datasource_1.runTransaction)(callback, funcName, { dsName: this.name, config });
|
|
183
156
|
}
|
|
184
|
-
registerTransaction(func,
|
|
185
|
-
return (0, datasource_1.registerTransaction)(this.name, func, { name
|
|
157
|
+
registerTransaction(func, name, config) {
|
|
158
|
+
return (0, datasource_1.registerTransaction)(this.name, func, { name }, config);
|
|
186
159
|
}
|
|
187
160
|
transaction(config) {
|
|
188
161
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
@@ -191,7 +164,7 @@ class NodePostgresDataSource {
|
|
|
191
164
|
if (!descriptor.value) {
|
|
192
165
|
throw Error('Use of decorator when original method is undefined');
|
|
193
166
|
}
|
|
194
|
-
descriptor.value = ds.registerTransaction(descriptor.value,
|
|
167
|
+
descriptor.value = ds.registerTransaction(descriptor.value, propertyKey.toString(), config);
|
|
195
168
|
return descriptor;
|
|
196
169
|
};
|
|
197
170
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA,gDAAgD;;;AAEhD,iDAAqE;AACrE,8DAWuC;AACvC,2BAAuF;AACvF,uDAAqD;AACrD,yCAAsC;AAQtC,MAAM,aAAa,GAAG,IAAI,oCAAiB,EAAiC,CAAC;AAE7E,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|