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.
@@ -4,6 +4,7 @@ export declare type Row = {
4
4
  };
5
5
  export declare class ConnectionFactory {
6
6
  private postgresPool;
7
+ private server;
7
8
  constructor(postgresUri: string);
8
9
  close(): Promise<void>;
9
10
  withTransaction<T>(callback: (connection: PoolClient) => Promise<T>): Promise<T>;
@@ -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 __awaiter(this, void 0, void 0, function* () {
84
- return yield this.postgresPool.connect();
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;IAG1B,YAAa,WAAmB;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,SAAI,CAAC;YACzB,gBAAgB,EAAE,WAAW;SAChC,CAAC,CAAC;IACP,CAAC;IAEK,KAAK;;YACP,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;QAClC,CAAC;KAAA;IAED,eAAe,CAAI,QAAgD;QAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,CAAM,UAAU,EAAC,EAAE;YAChC,qEAAqE;YACrE,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,OAAO,IAAI,EAAE;gBACT,IAAI;oBACA,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAChC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAC1C,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACjC,OAAO,MAAM,CAAC;iBACjB;gBACD,OAAO,CAAC,EAAE;oBACN,MAAM,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBACnC,IAAI,CAAC,YAAY,kBAAa,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE;wBAClD,QAAQ,EAAE,CAAC;wBACX,IAAI,QAAQ,KAAK,CAAC,EAAE;4BAChB,MAAM,CAAC,CAAC;yBACX;qBACJ;yBACI;wBACD,MAAM,CAAC,CAAC;qBACX;iBACJ;aACJ;QACL,CAAC,CAAA,CAAC,CAAA;IACN,CAAC;IAEK,IAAI,CAAI,QAAgD;;YAC1D,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC/C,OAAO,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE;gBAC3B,IAAI;oBACA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;oBACzC,IAAI;wBACA,OAAO,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;qBACjC;4BACO;wBACJ,MAAM,CAAC,OAAO,EAAE,CAAC;qBACpB;iBACJ;gBACD,OAAO,CAAC,EAAE;oBACN,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;wBACtB,MAAM,CAAC,CAAC;qBACX;oBACD,OAAO,EAAE,CAAC;oBACV,IAAI,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE;wBAC1B,MAAM,CAAC,CAAC;qBACX;iBACJ;gBACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;oBACpB,MAAM,IAAA,eAAK,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;iBAC/B;aACJ;YACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACnD,CAAC;KAAA;IAEa,YAAY;;YACtB,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC7C,CAAC;KAAA;CACJ;AAxED,8CAwEC;AAED,SAAS,gBAAgB,CAAC,CAAM;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc,EAAE;QAC3B,OAAO,IAAI,CAAC;KACf;IACD,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC;AACjB,CAAC"}
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.1",
2741
- "resolved": "https://registry.npmjs.org/jinaga/-/jinaga-5.1.1.tgz",
2742
- "integrity": "sha512-WAjXmcEslkFMLHuYUO2meeIV92LWRUkiI8ig4FTf/tWJBjTwBwdHfhErwmgOqjT9x81tWtFs6wy4MPZGPamm5Q==",
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,6 +1,6 @@
1
1
  {
2
2
  "name": "jinaga-server",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "Application-agnostic back end for web applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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 async createClient() {
76
- return await this.postgresPool.connect();
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
+ }