jinaga-server 2.1.3 → 2.1.5
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/postgres/connection.d.ts +1 -0
- package/dist/postgres/connection.js +27 -3
- package/dist/postgres/connection.js.map +1 -1
- package/docs/distribution-rules.txt +32 -0
- package/integration-test/jinaga-test/package-lock.json +3 -3
- package/package.json +1 -1
- package/src/postgres/connection.ts +33 -3
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.ConnectionFactory = void 0;
|
|
13
|
+
const jinaga_1 = require("jinaga");
|
|
13
14
|
const pg_1 = require("pg");
|
|
14
15
|
const promise_1 = require("../util/promise");
|
|
15
16
|
class ConnectionFactory {
|
|
@@ -17,6 +18,17 @@ class ConnectionFactory {
|
|
|
17
18
|
this.postgresPool = new pg_1.Pool({
|
|
18
19
|
connectionString: postgresUri
|
|
19
20
|
});
|
|
21
|
+
// Parse the Postgres URI to find the host name.
|
|
22
|
+
if (postgresUri.startsWith('postgres://')) {
|
|
23
|
+
const host = postgresUri.split('@')[1].split(':')[0];
|
|
24
|
+
this.server = host;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.server = 'localhost';
|
|
28
|
+
}
|
|
29
|
+
this.postgresPool.on('error', (err, client) => {
|
|
30
|
+
jinaga_1.Trace.error(err);
|
|
31
|
+
});
|
|
20
32
|
}
|
|
21
33
|
close() {
|
|
22
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -35,14 +47,17 @@ class ConnectionFactory {
|
|
|
35
47
|
return result;
|
|
36
48
|
}
|
|
37
49
|
catch (e) {
|
|
50
|
+
jinaga_1.Trace.warn("Postgres transaction error: " + describeError(e));
|
|
38
51
|
yield connection.query('ROLLBACK');
|
|
39
52
|
if (e instanceof pg_1.DatabaseError && e.code === '23505') {
|
|
53
|
+
jinaga_1.Trace.warn("Postgres duplicate key: retrying");
|
|
40
54
|
attempts--;
|
|
41
55
|
if (attempts === 0) {
|
|
42
56
|
throw e;
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
else {
|
|
60
|
+
jinaga_1.Trace.error(e);
|
|
46
61
|
throw e;
|
|
47
62
|
}
|
|
48
63
|
}
|
|
@@ -65,14 +80,17 @@ class ConnectionFactory {
|
|
|
65
80
|
}
|
|
66
81
|
catch (e) {
|
|
67
82
|
if (!isTransientError(e)) {
|
|
83
|
+
jinaga_1.Trace.error(e);
|
|
68
84
|
throw e;
|
|
69
85
|
}
|
|
86
|
+
jinaga_1.Trace.warn("Postgres transient error: " + describeError(e));
|
|
70
87
|
attempt++;
|
|
71
88
|
if (attempt === pause.length) {
|
|
72
89
|
throw e;
|
|
73
90
|
}
|
|
74
91
|
}
|
|
75
92
|
if (pause[attempt] > 0) {
|
|
93
|
+
jinaga_1.Trace.warn("Postgres retrying in " + pause[attempt] + "ms");
|
|
76
94
|
yield (0, promise_1.delay)(pause[attempt]);
|
|
77
95
|
}
|
|
78
96
|
}
|
|
@@ -80,8 +98,8 @@ class ConnectionFactory {
|
|
|
80
98
|
});
|
|
81
99
|
}
|
|
82
100
|
createClient() {
|
|
83
|
-
return
|
|
84
|
-
return
|
|
101
|
+
return jinaga_1.Trace.dependency('Postgres client', this.server, () => {
|
|
102
|
+
return this.postgresPool.connect();
|
|
85
103
|
});
|
|
86
104
|
}
|
|
87
105
|
}
|
|
@@ -90,7 +108,13 @@ function isTransientError(e) {
|
|
|
90
108
|
if (e.code === 'ECONNREFUSED') {
|
|
91
109
|
return true;
|
|
92
110
|
}
|
|
93
|
-
console.error("Postgres error:", e);
|
|
94
111
|
return false;
|
|
95
112
|
}
|
|
113
|
+
function describeError(e) {
|
|
114
|
+
const error = {
|
|
115
|
+
code: e.code,
|
|
116
|
+
message: e.message,
|
|
117
|
+
};
|
|
118
|
+
return JSON.stringify(error);
|
|
119
|
+
}
|
|
96
120
|
//# sourceMappingURL=connection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/postgres/connection.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2BAAqD;AACrD,6CAAwC;AAIxC,MAAa,iBAAiB;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/postgres/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Anybody can read approved comments
|
|
2
|
+
|
|
3
|
+
(site: Blog.Site) {
|
|
4
|
+
post: Blog.Post [
|
|
5
|
+
post->site: Blog.Site = site
|
|
6
|
+
!E {
|
|
7
|
+
deleted: Blog.Post.Deleted [
|
|
8
|
+
deleted->post: Blog.Post = post
|
|
9
|
+
]
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
comment: Blog.Comment [
|
|
13
|
+
comment->post: Blog.Post = post
|
|
14
|
+
E {
|
|
15
|
+
approved: Blog.Comment.Approved [
|
|
16
|
+
approved->comment: Blog.Comment = comment
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// The site owner can read all posts and comments
|
|
23
|
+
|
|
24
|
+
(site: Blog.Site, user: Jinaga.User) {
|
|
25
|
+
post: Blog.Post [
|
|
26
|
+
post->site: Blog.Site = site
|
|
27
|
+
post->owner: Jinaga.User = user
|
|
28
|
+
]
|
|
29
|
+
comment: Blog.Comment [
|
|
30
|
+
comment->post: Blog.Post = post
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -2737,9 +2737,9 @@
|
|
|
2737
2737
|
}
|
|
2738
2738
|
},
|
|
2739
2739
|
"node_modules/jinaga": {
|
|
2740
|
-
"version": "5.1.
|
|
2741
|
-
"resolved": "https://registry.npmjs.org/jinaga/-/jinaga-5.1.
|
|
2742
|
-
"integrity": "sha512-
|
|
2740
|
+
"version": "5.1.3",
|
|
2741
|
+
"resolved": "https://registry.npmjs.org/jinaga/-/jinaga-5.1.3.tgz",
|
|
2742
|
+
"integrity": "sha512-XCIyFbO0YFjGgbbf50qVa0DgbOkNPyYiOo1033pQRQPOOAp2Eov5DmA4Eaxf9RpiHRaF+ZOrjrleBaxbMd5l2A==",
|
|
2743
2743
|
"dependencies": {
|
|
2744
2744
|
"@stablelib/base64": "^1.0.1",
|
|
2745
2745
|
"@stablelib/sha512": "^1.0.1",
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Trace } from 'jinaga';
|
|
1
2
|
import { DatabaseError, Pool, PoolClient } from 'pg';
|
|
2
3
|
import { delay } from "../util/promise";
|
|
3
4
|
|
|
@@ -5,11 +6,25 @@ export type Row = { [key: string]: any };
|
|
|
5
6
|
|
|
6
7
|
export class ConnectionFactory {
|
|
7
8
|
private postgresPool: Pool;
|
|
9
|
+
private server: string;
|
|
8
10
|
|
|
9
11
|
constructor (postgresUri: string) {
|
|
10
12
|
this.postgresPool = new Pool({
|
|
11
13
|
connectionString: postgresUri
|
|
12
14
|
});
|
|
15
|
+
|
|
16
|
+
// Parse the Postgres URI to find the host name.
|
|
17
|
+
if (postgresUri.startsWith('postgres://')) {
|
|
18
|
+
const host = postgresUri.split('@')[1].split(':')[0];
|
|
19
|
+
this.server = host;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.server = 'localhost';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.postgresPool.on('error', (err, client) => {
|
|
26
|
+
Trace.error(err);
|
|
27
|
+
});
|
|
13
28
|
}
|
|
14
29
|
|
|
15
30
|
async close() {
|
|
@@ -28,14 +43,17 @@ export class ConnectionFactory {
|
|
|
28
43
|
return result;
|
|
29
44
|
}
|
|
30
45
|
catch (e) {
|
|
46
|
+
Trace.warn("Postgres transaction error: " + describeError(e));
|
|
31
47
|
await connection.query('ROLLBACK');
|
|
32
48
|
if (e instanceof DatabaseError && e.code === '23505') {
|
|
49
|
+
Trace.warn("Postgres duplicate key: retrying");
|
|
33
50
|
attempts--;
|
|
34
51
|
if (attempts === 0) {
|
|
35
52
|
throw e;
|
|
36
53
|
}
|
|
37
54
|
}
|
|
38
55
|
else {
|
|
56
|
+
Trace.error(e);
|
|
39
57
|
throw e;
|
|
40
58
|
}
|
|
41
59
|
}
|
|
@@ -58,22 +76,27 @@ export class ConnectionFactory {
|
|
|
58
76
|
}
|
|
59
77
|
catch (e) {
|
|
60
78
|
if (!isTransientError(e)) {
|
|
79
|
+
Trace.error(e);
|
|
61
80
|
throw e;
|
|
62
81
|
}
|
|
82
|
+
Trace.warn("Postgres transient error: " + describeError(e));
|
|
63
83
|
attempt++;
|
|
64
84
|
if (attempt === pause.length) {
|
|
65
85
|
throw e;
|
|
66
86
|
}
|
|
67
87
|
}
|
|
68
88
|
if (pause[attempt] > 0) {
|
|
89
|
+
Trace.warn("Postgres retrying in " + pause[attempt] + "ms");
|
|
69
90
|
await delay(pause[attempt]);
|
|
70
91
|
}
|
|
71
92
|
}
|
|
72
93
|
throw new Error("Number of attempts exceeded");
|
|
73
94
|
}
|
|
74
95
|
|
|
75
|
-
private
|
|
76
|
-
return
|
|
96
|
+
private createClient() {
|
|
97
|
+
return Trace.dependency('Postgres client', this.server, () => {
|
|
98
|
+
return this.postgresPool.connect();
|
|
99
|
+
});
|
|
77
100
|
}
|
|
78
101
|
}
|
|
79
102
|
|
|
@@ -81,6 +104,13 @@ function isTransientError(e: any) {
|
|
|
81
104
|
if (e.code === 'ECONNREFUSED') {
|
|
82
105
|
return true;
|
|
83
106
|
}
|
|
84
|
-
console.error("Postgres error:", e);
|
|
85
107
|
return false;
|
|
86
108
|
}
|
|
109
|
+
|
|
110
|
+
function describeError(e: any) {
|
|
111
|
+
const error = {
|
|
112
|
+
code: e.code,
|
|
113
|
+
message: e.message,
|
|
114
|
+
};
|
|
115
|
+
return JSON.stringify(error);
|
|
116
|
+
}
|