@rpcbase/server 0.356.0 → 0.357.0

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/boot/server.js CHANGED
@@ -23,5 +23,11 @@ server.listen(SERVER_PORT, "0.0.0.0", () => {
23
23
  console.log(`listening on 0.0.0.0:${SERVER_PORT}`)
24
24
  })
25
25
 
26
+ // graceful exit handler
27
+ process.on("SIGTERM", () => {
28
+ server.close(() => {
29
+ process.exit(0)
30
+ })
31
+ })
26
32
 
27
33
  module.exports = app
package/boot/shared.js CHANGED
@@ -3,8 +3,6 @@ if (typeof __RB_IS_WEBPACK__ === "undefined") {
3
3
  throw new Error("cannot run without webpack bundling")
4
4
  }
5
5
 
6
- require("source-map-support").install()
7
-
8
6
  require("./setup_env")
9
7
 
10
8
  require("../extend-expect")
package/boot/worker.js CHANGED
@@ -9,4 +9,27 @@ const queue = require("../queue")
9
9
 
10
10
  queue.start()
11
11
 
12
+ let _queue_listener
13
+
12
14
  register_queue_listener()
15
+ .then((arg) => {
16
+ _queue_listener = arg
17
+ })
18
+
19
+
20
+ const handle_graceful_exit = async () => {
21
+ const close_fns = [
22
+ queue.instance().close,
23
+ ]
24
+
25
+ if (_queue_listener) {
26
+ close_fns.push(_queue_listener.close)
27
+ }
28
+
29
+ await Promise.allSettled(close_fns.map(fn => fn()))
30
+
31
+ process.exit(0)
32
+ }
33
+
34
+ process.on("SIGTERM", handle_graceful_exit)
35
+ // process.on("SIGINT", handle_graceful_exit)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/server",
3
- "version": "0.356.0",
3
+ "version": "0.357.0",
4
4
  "license": "SSPL-1.0",
5
5
  "main": "./index.js",
6
6
  "scripts": {
@@ -84,7 +84,6 @@
84
84
  "request-ip": "3.3.0",
85
85
  "sift": "17.1.3",
86
86
  "socket.io": "4.7.5",
87
- "source-map-support": "0.5.21",
88
87
  "validator": "13.12.0"
89
88
  }
90
89
  }
@@ -8,22 +8,20 @@ const queue = require("./index")
8
8
 
9
9
  const dispatch_queue = require("./dispatch_queue")
10
10
 
11
-
12
11
  const log = debug("rb:queue:listener")
13
12
 
14
13
  const {RB_APP_NAME, RB_TENANT_ID} = process.env
15
14
 
16
- const RETRY_MAXIMUM_DELAY = 2000
17
- const RETRY_MINIMUM_DELAY = 10
18
- const MAX_RETRIES = 64
15
+ const RETRY_MAXIMUM_DELAY = 3000
16
+ const RETRY_MINIMUM_DELAY = 50
17
+ const MAX_RETRIES = 20
19
18
 
20
19
  // TODO: reset retry counters when connection becomes healthy again?
21
20
  let retry_counter = 0
21
+ let emitter = null
22
22
 
23
23
 
24
- // Listens for mongodb change events,
25
- // when a document is created, updated or deleted, dispatch job message
26
-
24
+ // TODO: use proper mongodb delete event here now
27
25
  // mongoose middleware used for delete events
28
26
  const mongoose_delete_plugin = (schema) => {
29
27
  schema.pre("deleteOne", function(next) {
@@ -70,38 +68,44 @@ const assert_doc_id = (change) => {
70
68
  }
71
69
 
72
70
  const dispatch_change_handler = (change) => {
73
- // skip if change is on another db
74
- if (change?.ns?.db !== RB_APP_NAME) {
75
- return
76
- }
77
-
71
+ // verify we have correct object ids
78
72
  assert_doc_id(change)
79
73
 
80
- const op = change.operationType
81
- if (["insert", "update"].includes(op)) {
82
- const coll_name = change.ns.coll
83
-
84
- const model_name = Object.keys(mongoose.models).find((k) => {
85
- return mongoose.models[k].collection.collectionName === coll_name
86
- })
74
+ const coll_name = change.ns.coll
87
75
 
88
- if (!model_name) {
89
- return
90
- }
76
+ const model_name = Object.keys(mongoose.models).find((k) => {
77
+ return mongoose.models[k].collection.collectionName === coll_name
78
+ })
91
79
 
92
- dispatch_queue(queue, model_name, op, change.fullDocument, change.updateDescription)
80
+ if (!model_name) {
81
+ return
93
82
  }
94
- }
95
83
 
84
+ dispatch_queue(queue, model_name, op, change.fullDocument, change.updateDescription)
85
+ }
96
86
 
97
87
  const register_db_emitter = () => {
88
+ // TODO: unclear why it's necessary to have this step here too even though we already removeListeners in the on close event
89
+ if (emitter) {
90
+ emitter.removeAllListeners()
91
+ emitter.close()
92
+ }
93
+
98
94
  log("registering db emitter")
99
95
 
100
96
  // TODO: implement delete operation fullDocument retrieve,
101
97
  // when this is released https://jira.mongodb.org/browse/SERVER-36941
102
98
  // this is done via a plugin right now
103
99
  // https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ChangeStreamOptions.html
104
- const emitter = mongoose.connection.watch({fullDocument: "updateLookup"})
100
+
101
+ // Set up the change stream with a filter to only listen to the specific database
102
+ const pipeline = [
103
+ { $match: { 'ns.db': RB_APP_NAME } },
104
+ { $match: { operationType: { $in: ["insert", "update", /*"delete"*/] } } }
105
+ ]
106
+
107
+ // https://www.mongodb.com/docs/manual/reference/method/Mongo.watch/
108
+ emitter = mongoose.connection.watch(pipeline, {fullDocument: "updateLookup"})
105
109
 
106
110
  emitter.on("change", dispatch_change_handler)
107
111
 
@@ -110,7 +114,9 @@ const register_db_emitter = () => {
110
114
  })
111
115
 
112
116
  emitter.on("close", (arg, arg2) => {
113
- // TODO: investigate why we disconnect here and can't reconnect easily
117
+ emitter.removeAllListeners()
118
+ emitter.close()
119
+
114
120
  retry_counter++
115
121
 
116
122
  if (retry_counter > MAX_RETRIES) {
@@ -130,18 +136,30 @@ const register_db_emitter = () => {
130
136
  emitter.on("end", (arg) => {
131
137
  console.log("EMITTER ENDED", arg)
132
138
  })
139
+
140
+ return emitter
133
141
  }
134
142
 
135
143
 
136
- const register_queue_listener = () => {
144
+ const register_queue_listener = () => new Promise((resolve, reject) => {
137
145
  // register the mongoose delete plugin
138
146
  log("registering mongoose_delete_plugin")
139
147
  mongoose.plugin(mongoose_delete_plugin)
140
148
 
141
149
  mongoose.connection.once("open", () => {
142
- register_db_emitter()
150
+ const emitter = register_db_emitter()
151
+ resolve(emitter)
143
152
  })
144
- }
153
+
154
+ mongoose.connection.on("error", (err) => {
155
+ console.log("register_queue_listener:", "mongoose connection error", err)
156
+ // reject(err)
157
+ })
158
+
159
+ mongoose.connection.on("disconnected", (err) => {
160
+ console.log("mongodb:", "mongodb disconnected", err)
161
+ })
162
+ })
145
163
 
146
164
 
147
165
  module.exports = register_queue_listener