prostgles-server 4.2.79 → 4.2.81
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/PubSubManager/PubSubManager.js +6 -6
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/getInitQuery.d.ts +5 -1
- package/dist/PubSubManager/getInitQuery.d.ts.map +1 -1
- package/dist/PubSubManager/getInitQuery.js +48 -30
- package/dist/PubSubManager/getInitQuery.js.map +1 -1
- package/dist/PubSubManager/getPubSubManagerInitQuery.d.ts +13 -0
- package/dist/PubSubManager/getPubSubManagerInitQuery.d.ts.map +1 -0
- package/dist/PubSubManager/getPubSubManagerInitQuery.js +616 -0
- package/dist/PubSubManager/getPubSubManagerInitQuery.js.map +1 -0
- package/dist/PubSubManager/initPubSubManager.d.ts +1 -0
- package/dist/PubSubManager/initPubSubManager.d.ts.map +1 -1
- package/dist/PubSubManager/initPubSubManager.js +34 -4
- package/dist/PubSubManager/initPubSubManager.js.map +1 -1
- package/lib/PubSubManager/PubSubManager.ts +1 -1
- package/lib/PubSubManager/{getInitQuery.ts → getPubSubManagerInitQuery.ts} +50 -31
- package/lib/PubSubManager/initPubSubManager.ts +35 -3
- package/package.json +3 -3
- package/tests/client/package-lock.json +8 -29
- package/tests/clientOnlyQueries.spec.ts +27 -0
- package/tests/server/package-lock.json +126 -68
- package/tests/server/package.json +2 -2
|
@@ -1,17 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initPubSubManager = exports.REALTIME_TRIGGER_CHECK_QUERY = void 0;
|
|
3
|
+
exports.initPubSubManager = exports.tout = exports.REALTIME_TRIGGER_CHECK_QUERY = void 0;
|
|
4
|
+
const prostgles_types_1 = require("prostgles-types");
|
|
4
5
|
const PostgresNotifListenManager_1 = require("../PostgresNotifListenManager");
|
|
5
6
|
const getWatchSchemaTagList_1 = require("../SchemaWatch/getWatchSchemaTagList");
|
|
6
7
|
const PubSubManager_1 = require("./PubSubManager");
|
|
7
|
-
const
|
|
8
|
+
const getPubSubManagerInitQuery_1 = require("./getPubSubManagerInitQuery");
|
|
8
9
|
exports.REALTIME_TRIGGER_CHECK_QUERY = "prostgles-server internal query used to manage realtime triggers";
|
|
10
|
+
const tout = (ms) => new Promise(res => setTimeout(res, ms));
|
|
11
|
+
exports.tout = tout;
|
|
9
12
|
async function initPubSubManager() {
|
|
10
13
|
if (!this.getIsDestroyed())
|
|
11
14
|
return undefined;
|
|
12
15
|
try {
|
|
13
|
-
const initQuery = await
|
|
14
|
-
|
|
16
|
+
const initQuery = await getPubSubManagerInitQuery_1.getPubSubManagerInitQuery.bind(this)();
|
|
17
|
+
/**
|
|
18
|
+
* High database activity might cause deadlocks.
|
|
19
|
+
* Must retry
|
|
20
|
+
*/
|
|
21
|
+
let didDeadlock = false;
|
|
22
|
+
let tries = 3;
|
|
23
|
+
let error;
|
|
24
|
+
while ((0, prostgles_types_1.isDefined)(initQuery) && tries > 0) {
|
|
25
|
+
try {
|
|
26
|
+
/** Try to reduce race condition deadlocks due to multiple clients connecting at the same time */
|
|
27
|
+
await (0, exports.tout)(Math.random());
|
|
28
|
+
await this.db.any(initQuery);
|
|
29
|
+
error = undefined;
|
|
30
|
+
tries = 0;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
if (!didDeadlock && (0, prostgles_types_1.isObject)(e) && e.code === "40P01") {
|
|
34
|
+
didDeadlock = true;
|
|
35
|
+
tries = 5;
|
|
36
|
+
console.error("Deadlock detected. Retrying...");
|
|
37
|
+
}
|
|
38
|
+
error = e;
|
|
39
|
+
tries--;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (error) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
15
45
|
if (!this.getIsDestroyed())
|
|
16
46
|
return;
|
|
17
47
|
/* Prepare App id */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initPubSubManager.js","sourceRoot":"","sources":["../../lib/PubSubManager/initPubSubManager.ts"],"names":[],"mappings":";;;AAAA,8EAA2E;AAC3E,gFAA6E;AAC7E,mDAAwE;AACxE,
|
|
1
|
+
{"version":3,"file":"initPubSubManager.js","sourceRoot":"","sources":["../../lib/PubSubManager/initPubSubManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ import { EventTypes } from "../Logging";
|
|
|
22
22
|
import { TableRule } from "../PublishParser/PublishParser";
|
|
23
23
|
import { syncData } from "../SyncReplication";
|
|
24
24
|
import { addSub } from "./addSub";
|
|
25
|
-
import { DB_OBJ_NAMES } from "./
|
|
25
|
+
import { DB_OBJ_NAMES } from "./getPubSubManagerInitQuery";
|
|
26
26
|
import { notifListener } from "./notifListener";
|
|
27
27
|
import { pushSubData } from "./pushSubData";
|
|
28
28
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
|
|
2
|
+
import { tryCatch } from "prostgles-types";
|
|
3
|
+
import { pgp } from "../DboBuilder/DboBuilderTypes";
|
|
2
4
|
import { asValue, NOTIF_CHANNEL, NOTIF_TYPE, PubSubManager } from "./PubSubManager";
|
|
3
5
|
const { version } = require("../../package.json");
|
|
4
6
|
import { getAppCheckQuery } from "./orphanTriggerCheck";
|
|
@@ -10,14 +12,23 @@ export const DB_OBJ_NAMES = {
|
|
|
10
12
|
schema_watch_trigger: "prostgles_schema_watch_trigger_new"
|
|
11
13
|
} as const;
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const PROSTGLES_SCHEMA_EXISTS_QUERY = `
|
|
16
|
+
SELECT 1
|
|
17
|
+
FROM information_schema.columns
|
|
18
|
+
WHERE table_schema = 'prostgles'
|
|
19
|
+
AND table_name = 'versions'
|
|
20
|
+
AND column_name = 'schema_md5'
|
|
21
|
+
`;
|
|
22
|
+
const PROSTGLES_SCHEMA_VERSION_OK_QUERY = `
|
|
23
|
+
SELECT 1
|
|
24
|
+
FROM prostgles.versions
|
|
25
|
+
WHERE (string_to_array(version, '.')::int[] > string_to_array(\${version}, '.')::int[])
|
|
26
|
+
OR (string_to_array(version, '.')::int[] = string_to_array(\${version}, '.')::int[])
|
|
27
|
+
AND schema_md5 = \${schema_md5}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
const getInitQuery = (debugMode: boolean | undefined) => `
|
|
31
|
+
BEGIN; -- TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
|
21
32
|
|
|
22
33
|
--SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
|
|
23
34
|
|
|
@@ -29,9 +40,6 @@ DO
|
|
|
29
40
|
$do$
|
|
30
41
|
BEGIN
|
|
31
42
|
|
|
32
|
-
/* Reduce deadlocks */
|
|
33
|
-
PERFORM pg_sleep(random());
|
|
34
|
-
|
|
35
43
|
/* Drop older version. */
|
|
36
44
|
IF EXISTS (SELECT 1 FROM information_schema.schemata WHERE schema_name = 'prostgles') THEN
|
|
37
45
|
|
|
@@ -39,23 +47,14 @@ BEGIN
|
|
|
39
47
|
IF
|
|
40
48
|
/* Backwards compatibility. Cannot check schema version */
|
|
41
49
|
NOT EXISTS(
|
|
42
|
-
|
|
43
|
-
FROM information_schema.columns
|
|
44
|
-
WHERE table_schema = 'prostgles'
|
|
45
|
-
AND table_name = 'versions'
|
|
46
|
-
AND column_name = 'schema_md5'
|
|
50
|
+
${PROSTGLES_SCHEMA_EXISTS_QUERY}
|
|
47
51
|
)
|
|
48
52
|
THEN
|
|
49
53
|
DROP SCHEMA IF EXISTS prostgles CASCADE;
|
|
50
54
|
ELSIF
|
|
51
55
|
/* There is no newer version or same same version but different schema */
|
|
52
56
|
NOT EXISTS (
|
|
53
|
-
|
|
54
|
-
FROM prostgles.versions
|
|
55
|
-
WHERE
|
|
56
|
-
(string_to_array(version, '.')::int[] > string_to_array(${asValue(version)}, '.')::int[])
|
|
57
|
-
OR (string_to_array(version, '.')::int[] = string_to_array(${asValue(version)}, '.')::int[])
|
|
58
|
-
AND schema_md5 = ${asValue(schema_md5)}
|
|
57
|
+
${PROSTGLES_SCHEMA_VERSION_OK_QUERY}
|
|
59
58
|
)
|
|
60
59
|
THEN
|
|
61
60
|
DROP SCHEMA IF EXISTS prostgles CASCADE;
|
|
@@ -83,7 +82,7 @@ BEGIN
|
|
|
83
82
|
COMMENT ON TABLE prostgles.versions IS 'Stores the prostgles schema creation query hash and package version number to identify when a newer schema needs to be re-created';
|
|
84
83
|
|
|
85
84
|
INSERT INTO prostgles.versions(version, schema_md5)
|
|
86
|
-
VALUES(${asValue(version)},
|
|
85
|
+
VALUES(${asValue(version)}, \${schema_md5})
|
|
87
86
|
ON CONFLICT DO NOTHING;
|
|
88
87
|
|
|
89
88
|
|
|
@@ -307,7 +306,7 @@ BEGIN
|
|
|
307
306
|
THEN concat_ws('; ', 'error', err_text, err_detail, err_hint, 'query: ' || query )
|
|
308
307
|
ELSE COALESCE(v_trigger.cids, '')
|
|
309
308
|
END
|
|
310
|
-
${
|
|
309
|
+
${debugMode? (", COALESCE(current_query(), 'current_query ??'), ' ', query") : ""}
|
|
311
310
|
), 7999/4) -- Some chars are 2bytes -> 'Ω'
|
|
312
311
|
);
|
|
313
312
|
END LOOP;
|
|
@@ -506,7 +505,7 @@ BEGIN
|
|
|
506
505
|
json_build_object(
|
|
507
506
|
'TG_OP', TG_OP,
|
|
508
507
|
'duration', (EXTRACT(EPOCH FROM now()) * 1000) - start_time,
|
|
509
|
-
'query', ${
|
|
508
|
+
'query', ${debugMode? 'LEFT(current_query(), 400)' : "'Only shown in debug mode'"}
|
|
510
509
|
)
|
|
511
510
|
)::TEXT, 7999/4)
|
|
512
511
|
);
|
|
@@ -568,7 +567,7 @@ BEGIN
|
|
|
568
567
|
${asValue(NOTIF_TYPE.schema)},
|
|
569
568
|
tg_tag ,
|
|
570
569
|
TG_event,
|
|
571
|
-
${
|
|
570
|
+
${debugMode? 'curr_query' : "'Only shown in debug mode'"}
|
|
572
571
|
), 7999/4)
|
|
573
572
|
);
|
|
574
573
|
END LOOP;
|
|
@@ -589,11 +588,31 @@ BEGIN
|
|
|
589
588
|
END
|
|
590
589
|
$do$;
|
|
591
590
|
|
|
592
|
-
|
|
593
591
|
COMMIT;
|
|
594
|
-
`
|
|
595
|
-
|
|
596
|
-
|
|
592
|
+
`
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Initialize the prostgles schema and functions needed for realtime data and schema changes
|
|
596
|
+
* undefined returned if the database contains the apropriate prostgles schema
|
|
597
|
+
*/
|
|
598
|
+
export const getPubSubManagerInitQuery = async function(this: PubSubManager): Promise<string | undefined> {
|
|
599
|
+
|
|
600
|
+
const initQuery = getInitQuery(this.dboBuilder.prostgles.opts.DEBUG_MODE);
|
|
601
|
+
const { schema_md5 = "none" } = await this.db.oneOrNone("SELECT md5($1) as schema_md5", [initQuery.trim()]);
|
|
602
|
+
const query = pgp.as.format(initQuery, { schema_md5, version });
|
|
603
|
+
const existingSchema = await this.db.any(PROSTGLES_SCHEMA_EXISTS_QUERY);
|
|
604
|
+
if(!existingSchema.length){
|
|
605
|
+
return query;
|
|
606
|
+
}
|
|
607
|
+
const { existingSchemaVersions } = await tryCatch(async () => {
|
|
608
|
+
const existingSchemaVersions = await this.db.any(PROSTGLES_SCHEMA_VERSION_OK_QUERY, { schema_md5, version });
|
|
609
|
+
return {
|
|
610
|
+
existingSchemaVersions
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
if(!existingSchemaVersions?.length){
|
|
614
|
+
return query;
|
|
615
|
+
}
|
|
597
616
|
|
|
598
|
-
return
|
|
617
|
+
return undefined;
|
|
599
618
|
}
|
|
@@ -1,16 +1,48 @@
|
|
|
1
|
+
import { isDefined, isObject } from "prostgles-types";
|
|
1
2
|
import { PostgresNotifListenManager } from "../PostgresNotifListenManager";
|
|
2
3
|
import { getWatchSchemaTagList } from "../SchemaWatch/getWatchSchemaTagList";
|
|
3
4
|
import { NOTIF_CHANNEL, PubSubManager, asValue } from "./PubSubManager";
|
|
4
|
-
import {
|
|
5
|
+
import { getPubSubManagerInitQuery } from "./getPubSubManagerInitQuery";
|
|
5
6
|
export const REALTIME_TRIGGER_CHECK_QUERY = "prostgles-server internal query used to manage realtime triggers" as const;
|
|
6
7
|
|
|
8
|
+
export const tout = (ms: number) => new Promise(res => setTimeout(res, ms));
|
|
9
|
+
|
|
7
10
|
export async function initPubSubManager(this: PubSubManager): Promise<PubSubManager | undefined> {
|
|
8
11
|
if (!this.getIsDestroyed()) return undefined;
|
|
9
12
|
|
|
10
13
|
try {
|
|
11
14
|
|
|
12
|
-
const initQuery = await
|
|
13
|
-
|
|
15
|
+
const initQuery = await getPubSubManagerInitQuery.bind(this)();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* High database activity might cause deadlocks.
|
|
19
|
+
* Must retry
|
|
20
|
+
*/
|
|
21
|
+
let didDeadlock = false;
|
|
22
|
+
let tries = 3;
|
|
23
|
+
let error: any;
|
|
24
|
+
while (isDefined(initQuery) && tries > 0) {
|
|
25
|
+
try {
|
|
26
|
+
/** Try to reduce race condition deadlocks due to multiple clients connecting at the same time */
|
|
27
|
+
await tout(Math.random());
|
|
28
|
+
|
|
29
|
+
await this.db.any(initQuery);
|
|
30
|
+
error = undefined;
|
|
31
|
+
tries = 0;
|
|
32
|
+
} catch (e: any) {
|
|
33
|
+
if(!didDeadlock && isObject(e) && e.code === "40P01"){
|
|
34
|
+
didDeadlock = true;
|
|
35
|
+
tries = 5;
|
|
36
|
+
console.error("Deadlock detected. Retrying...");
|
|
37
|
+
}
|
|
38
|
+
error = e;
|
|
39
|
+
tries --;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if(error){
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
|
|
14
46
|
if (!this.getIsDestroyed()) return;
|
|
15
47
|
|
|
16
48
|
/* Prepare App id */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prostgles-server",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.81",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"check-disk-space": "^3.4.0",
|
|
41
41
|
"file-type": "^18.5.0",
|
|
42
42
|
"pg": "^8.11.5",
|
|
43
|
-
"pg-cursor": "^2.
|
|
44
|
-
"pg-promise": "^11.
|
|
43
|
+
"pg-cursor": "^2.11.0",
|
|
44
|
+
"pg-promise": "^11.8.0",
|
|
45
45
|
"prostgles-client": "^4.0.53",
|
|
46
46
|
"prostgles-types": "^4.0.87"
|
|
47
47
|
},
|
|
@@ -121,14 +121,14 @@
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
"node_modules/engine.io-client": {
|
|
124
|
-
"version": "6.5.
|
|
125
|
-
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.
|
|
126
|
-
"integrity": "sha512-
|
|
124
|
+
"version": "6.5.4",
|
|
125
|
+
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz",
|
|
126
|
+
"integrity": "sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==",
|
|
127
127
|
"dependencies": {
|
|
128
128
|
"@socket.io/component-emitter": "~3.1.0",
|
|
129
129
|
"debug": "~4.3.1",
|
|
130
130
|
"engine.io-parser": "~5.2.1",
|
|
131
|
-
"ws": "~8.
|
|
131
|
+
"ws": "~8.17.1",
|
|
132
132
|
"xmlhttprequest-ssl": "~2.0.0"
|
|
133
133
|
}
|
|
134
134
|
},
|
|
@@ -268,27 +268,6 @@
|
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
},
|
|
271
|
-
"node_modules/jsdom/node_modules/ws": {
|
|
272
|
-
"version": "8.16.0",
|
|
273
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
|
|
274
|
-
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
|
|
275
|
-
"dev": true,
|
|
276
|
-
"engines": {
|
|
277
|
-
"node": ">=10.0.0"
|
|
278
|
-
},
|
|
279
|
-
"peerDependencies": {
|
|
280
|
-
"bufferutil": "^4.0.1",
|
|
281
|
-
"utf-8-validate": ">=5.0.2"
|
|
282
|
-
},
|
|
283
|
-
"peerDependenciesMeta": {
|
|
284
|
-
"bufferutil": {
|
|
285
|
-
"optional": true
|
|
286
|
-
},
|
|
287
|
-
"utf-8-validate": {
|
|
288
|
-
"optional": true
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
},
|
|
292
271
|
"node_modules/json-schema": {
|
|
293
272
|
"version": "0.4.0",
|
|
294
273
|
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
|
@@ -615,15 +594,15 @@
|
|
|
615
594
|
}
|
|
616
595
|
},
|
|
617
596
|
"node_modules/ws": {
|
|
618
|
-
"version": "8.
|
|
619
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.
|
|
620
|
-
"integrity": "sha512-
|
|
597
|
+
"version": "8.17.1",
|
|
598
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
|
599
|
+
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
|
621
600
|
"engines": {
|
|
622
601
|
"node": ">=10.0.0"
|
|
623
602
|
},
|
|
624
603
|
"peerDependencies": {
|
|
625
604
|
"bufferutil": "^4.0.1",
|
|
626
|
-
"utf-8-validate": "
|
|
605
|
+
"utf-8-validate": ">=5.0.2"
|
|
627
606
|
},
|
|
628
607
|
"peerDependenciesMeta": {
|
|
629
608
|
"bufferutil": {
|
|
@@ -8,6 +8,33 @@ import { describe, test } from "node:test";
|
|
|
8
8
|
export const clientOnlyQueries = async (db: DBHandlerClient, auth: Auth, log: (...args: any[]) => any, methods, tableSchema: DBSchemaTable[], token: string) => {
|
|
9
9
|
|
|
10
10
|
await describe("Client only queries", async (t) => {
|
|
11
|
+
|
|
12
|
+
await test("SQL Stream more than 1k records", async ( ) => {
|
|
13
|
+
const expectedRowCount = 2e3;
|
|
14
|
+
await tryRunP("", async (resolve, reject) => {
|
|
15
|
+
let rows: any[] = [];
|
|
16
|
+
const res = await db.sql!(`SELECT * FROM generate_series(1, ${expectedRowCount})`, {}, { returnType: "stream" });
|
|
17
|
+
const listener = async (packet: SocketSQLStreamPacket) => {
|
|
18
|
+
if(packet.type === "error"){
|
|
19
|
+
reject(packet.error);
|
|
20
|
+
} else {
|
|
21
|
+
if(packet.rows){
|
|
22
|
+
rows = [
|
|
23
|
+
...rows,
|
|
24
|
+
...packet.rows
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
if(packet.ended){
|
|
28
|
+
assert.equal(packet.ended, true);
|
|
29
|
+
assert.equal(rows.length, expectedRowCount);
|
|
30
|
+
resolve("ok");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
await res.start(listener);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
11
38
|
await test("SQL Stream persistedConnection with streamLimit works for subsequent queries", async () => {
|
|
12
39
|
await tryRunP("", async (resolve, reject) => {
|
|
13
40
|
const query = "SELECT * FROM generate_series(1, 100)";
|