@dbos-inc/node-pg-datasource 3.0.6-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 +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +173 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/index.ts +240 -0
- package/jest.config.js +8 -0
- package/package.json +32 -0
- package/tests/config.test.ts +31 -0
- package/tests/datasource.test.ts +320 -0
- package/tests/test-helpers.ts +12 -0
- package/tsconfig.json +9 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PGTransactionConfig as NodePostgresTransactionOptions, DBOSDataSource } from '@dbos-inc/dbos-sdk/datasource';
|
|
2
|
+
import { type ClientBase, type ClientConfig, type PoolConfig } from 'pg';
|
|
3
|
+
export { NodePostgresTransactionOptions };
|
|
4
|
+
export declare class NodePostgresDataSource implements DBOSDataSource<NodePostgresTransactionOptions> {
|
|
5
|
+
#private;
|
|
6
|
+
static get client(): ClientBase;
|
|
7
|
+
static initializeInternalSchema(config: ClientConfig): Promise<void>;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
constructor(name: string, config: PoolConfig);
|
|
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>, 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
|
+
}
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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;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
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// using https://github.com/brianc/node-postgres
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.NodePostgresDataSource = void 0;
|
|
5
|
+
const dbos_sdk_1 = require("@dbos-inc/dbos-sdk");
|
|
6
|
+
const datasource_1 = require("@dbos-inc/dbos-sdk/datasource");
|
|
7
|
+
const pg_1 = require("pg");
|
|
8
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
9
|
+
const superjson_1 = require("superjson");
|
|
10
|
+
const asyncLocalCtx = new node_async_hooks_1.AsyncLocalStorage();
|
|
11
|
+
class NodePGDSTH {
|
|
12
|
+
name;
|
|
13
|
+
dsType = 'NodePostgresDataSource';
|
|
14
|
+
#pool;
|
|
15
|
+
constructor(name, config) {
|
|
16
|
+
this.name = name;
|
|
17
|
+
this.#pool = new pg_1.Pool(config);
|
|
18
|
+
}
|
|
19
|
+
initialize() {
|
|
20
|
+
return Promise.resolve();
|
|
21
|
+
}
|
|
22
|
+
destroy() {
|
|
23
|
+
return this.#pool.end();
|
|
24
|
+
}
|
|
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;
|
|
30
|
+
}
|
|
31
|
+
static async #recordOutput(client, workflowID, functionNum, output) {
|
|
32
|
+
try {
|
|
33
|
+
await client.query(
|
|
34
|
+
/*sql*/
|
|
35
|
+
`INSERT INTO dbos.transaction_completion (workflow_id, function_num, output)
|
|
36
|
+
VALUES ($1, $2, $3)`, [workflowID, functionNum, output]);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if ((0, datasource_1.isPGKeyConflictError)(error)) {
|
|
40
|
+
throw new dbos_sdk_1.DBOSWorkflowConflictError(workflowID);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async #transaction(func, config = {}) {
|
|
48
|
+
const isolationLevel = config?.isolationLevel ? `ISOLATION LEVEL ${config.isolationLevel}` : '';
|
|
49
|
+
const readOnly = config?.readOnly ?? false;
|
|
50
|
+
const accessMode = config?.readOnly === undefined ? '' : readOnly ? 'READ ONLY' : 'READ WRITE';
|
|
51
|
+
const client = await this.#pool.connect();
|
|
52
|
+
try {
|
|
53
|
+
await client.query(/*sql*/ `BEGIN ${isolationLevel} ${accessMode}`);
|
|
54
|
+
const result = await func(client);
|
|
55
|
+
await client.query(/*sql*/ `COMMIT`);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
await client.query(/*sql*/ `ROLLBACK`);
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
client.release();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async invokeTransactionFunction(config, target, func, ...args) {
|
|
67
|
+
const workflowID = dbos_sdk_1.DBOS.workflowID;
|
|
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.');
|
|
74
|
+
}
|
|
75
|
+
const readOnly = config?.readOnly ?? false;
|
|
76
|
+
let retryWaitMS = 1;
|
|
77
|
+
const backoffFactor = 1.5;
|
|
78
|
+
const maxRetryWaitMS = 2000;
|
|
79
|
+
while (true) {
|
|
80
|
+
try {
|
|
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
|
+
}
|
|
87
|
+
// execute user's transaction function
|
|
88
|
+
const result = await asyncLocalCtx.run({ client }, async () => {
|
|
89
|
+
return (await func.call(target, ...args));
|
|
90
|
+
});
|
|
91
|
+
// save the output of read/write transactions
|
|
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
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}, { isolationLevel: config?.isolationLevel, readOnly: config?.readOnly });
|
|
101
|
+
// TODO: span.setStatus({ code: SpanStatusCode.OK });
|
|
102
|
+
// TODO: this.tracer.endSpan(span);
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if ((0, datasource_1.isPGRetriableTransactionError)(error)) {
|
|
107
|
+
// TODO: span.addEvent('TXN SERIALIZATION FAILURE', { retryWaitMillis: retryWaitMillis }, performance.now());
|
|
108
|
+
await new Promise((resolve) => setTimeout(resolve, retryWaitMS));
|
|
109
|
+
retryWaitMS = Math.min(retryWaitMS * backoffFactor, maxRetryWaitMS);
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
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.
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
class NodePostgresDataSource {
|
|
126
|
+
static get client() {
|
|
127
|
+
if (!dbos_sdk_1.DBOS.isInTransaction()) {
|
|
128
|
+
throw new Error('invalid use of NodePostgresDataSource.client outside of a DBOS transaction.');
|
|
129
|
+
}
|
|
130
|
+
const ctx = asyncLocalCtx.getStore();
|
|
131
|
+
if (!ctx) {
|
|
132
|
+
throw new Error('No async local context found.');
|
|
133
|
+
}
|
|
134
|
+
return ctx.client;
|
|
135
|
+
}
|
|
136
|
+
static async initializeInternalSchema(config) {
|
|
137
|
+
const client = new pg_1.Client(config);
|
|
138
|
+
try {
|
|
139
|
+
await client.connect();
|
|
140
|
+
await client.query(datasource_1.createTransactionCompletionSchemaPG);
|
|
141
|
+
await client.query(datasource_1.createTransactionCompletionTablePG);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
await client.end();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
name;
|
|
148
|
+
#provider;
|
|
149
|
+
constructor(name, config) {
|
|
150
|
+
this.name = name;
|
|
151
|
+
this.#provider = new NodePGDSTH(name, config);
|
|
152
|
+
(0, datasource_1.registerDataSource)(this.#provider);
|
|
153
|
+
}
|
|
154
|
+
async runTransaction(callback, funcName, config) {
|
|
155
|
+
return await (0, datasource_1.runTransaction)(callback, funcName, { dsName: this.name, config });
|
|
156
|
+
}
|
|
157
|
+
registerTransaction(func, name, config) {
|
|
158
|
+
return (0, datasource_1.registerTransaction)(this.name, func, { name }, config);
|
|
159
|
+
}
|
|
160
|
+
transaction(config) {
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
162
|
+
const ds = this;
|
|
163
|
+
return function decorator(_target, propertyKey, descriptor) {
|
|
164
|
+
if (!descriptor.value) {
|
|
165
|
+
throw Error('Use of decorator when original method is undefined');
|
|
166
|
+
}
|
|
167
|
+
descriptor.value = ds.registerTransaction(descriptor.value, propertyKey.toString(), config);
|
|
168
|
+
return descriptor;
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.NodePostgresDataSource = NodePostgresDataSource;
|
|
173
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|