@superhero/core 4.0.0-beta.7 → 4.0.1

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/README.md CHANGED
@@ -44,10 +44,9 @@ await core.bootstrap()
44
44
 
45
45
  // Locate a service
46
46
  const myService = core.locate('myService')
47
- console.log(myService)
48
47
 
49
48
  // Graceful shutdown
50
- await core.destruct()
49
+ await core.destroy()
51
50
  ```
52
51
 
53
52
  ### Clustering Example
@@ -66,8 +65,8 @@ await core.add('./path/to/config.js')
66
65
  // Bootstrap core
67
66
  await core.bootstrap()
68
67
 
69
- // Destruct core when done
70
- await core.destruct()
68
+ // Destroy core when done
69
+ await core.destroy()
71
70
  ```
72
71
 
73
72
  ---
@@ -125,11 +124,11 @@ pass 4
125
124
  ---------------------------------------------------------------------------------------------------
126
125
  file | line % | branch % | funcs % | uncovered lines
127
126
  ---------------------------------------------------------------------------------------------------
128
- index.js | 74.64 | 67.42 | 76.00 | 103-106 125-127 135-140 143-145 189-194 205-210 2…
127
+ index.js | 74.21 | 67.03 | 74.51 | 19-24 97-100 121-123 131-136 139-141 185-190 201-2…
129
128
  index.test.js | 100.00 | 100.00 | 100.00 |
130
129
  worker.js | 100.00 | 100.00 | 100.00 |
131
130
  ---------------------------------------------------------------------------------------------------
132
- all files | 77.97 | 70.41 | 78.95 |
131
+ all files | 77.46 | 70.00 | 77.59 |
133
132
  ---------------------------------------------------------------------------------------------------
134
133
  ```
135
134
 
@@ -157,7 +156,7 @@ new Core(branch: string = undefined)
157
156
  - **`cluster(forks: number, branch?: number, version?: number): Promise<number>`**
158
157
  Start clustering with the specified number of workers.
159
158
 
160
- - **`destruct(): Promise<void>`**
159
+ - **`destroy(): Promise<void>`**
161
160
  Gracefully shutdown the core, its workers, and services.
162
161
 
163
162
  #### Properties
package/index.js CHANGED
@@ -3,14 +3,25 @@ import cluster from 'node:cluster'
3
3
  import EventEmitter from 'node:events'
4
4
  import path from 'node:path'
5
5
  import bootstrap from '@superhero/bootstrap'
6
- import Config from '@superhero/config'
7
6
  import Locate from '@superhero/locator'
8
7
  import Log from '@superhero/log'
9
8
 
10
9
  export default class Core
11
10
  {
12
11
  locate = new Locate
13
- config = new Config
12
+
13
+ get config()
14
+ {
15
+ return this.locate.config
16
+ }
17
+
18
+ set config(_)
19
+ {
20
+ const error = new Error('Can not set the config (read-only) property')
21
+ error.code = 'E_CORE_CONFIG_SET'
22
+ error.cause = 'Alter the config instance through the bundled locator'
23
+ throw error
24
+ }
14
25
 
15
26
  /**
16
27
  * @param {string} branch The branch to use to add branch specific configurations.
@@ -19,8 +30,7 @@ export default class Core
19
30
  {
20
31
  this.branch = branch
21
32
  this.basePath = this.locate.pathResolver.basePath // synchronize the base path.
22
- this.locate.set('@superhero/config', this.config)
23
- Core.#setupDestructor(this)
33
+ Core.#setupDestroyer(this)
24
34
  }
25
35
 
26
36
  #branch
@@ -56,69 +66,71 @@ export default class Core
56
66
  static #cores = new Map
57
67
 
58
68
  // Used to prevent multiple observers on the process events.
59
- static #destructorIsSetup = false
69
+ static #destroyerIsSetup = false
60
70
 
61
- // Used to prevent multiple destruct calls.
62
- static #destructorIsTriggered = false
71
+ // Used to prevent multiple destroy calls.
72
+ static #destroyerIsTriggered = false
63
73
 
64
- static #setupDestructor(core)
74
+ static #setupDestroyer(core)
65
75
  {
66
76
  Core.#cores.set(core, core)
67
77
 
68
- if(false === Core.#destructorIsSetup)
78
+ if(false === Core.#destroyerIsSetup)
69
79
  {
70
- Core.#destructorIsSetup = true
80
+ Core.#destroyerIsSetup = true
71
81
 
72
- process.on('SIGINT', (signal) => Core.#destructor(signal))
73
- process.on('SIGTERM', (signal) => Core.#destructor(signal))
82
+ process.on('SIGINT', (signal) => Core.#destroy(signal))
83
+ process.on('SIGTERM', (signal) => Core.#destroy(signal))
74
84
 
75
- process.on('unhandledRejection', (reason) => Core.#destructor(false, reason))
76
- process.on('uncaughtException', (error) => Core.#destructor(false, error))
85
+ process.on('unhandledRejection', (reason) => Core.#destroy(false, reason))
86
+ process.on('uncaughtException', (error) => Core.#destroy(false, error))
77
87
  }
78
88
  }
79
89
 
80
90
  /**
81
- * Attempts to destruct all core instances gracefully.
91
+ * Attempts to destroy all core instances gracefully.
82
92
  */
83
- static async #destructor(signal, reason)
93
+ static async #destroy(signal, reason)
84
94
  {
85
- if(Core.#destructorIsTriggered)
95
+ if(Core.#destroyerIsTriggered)
86
96
  {
87
97
  Core.log.info`redundant shutdown signal ${signal} waiting for previous shutdown process to finalize…`
88
98
  reason && Core.log.fail`${reason}`
89
99
  return
90
100
  }
91
101
 
92
- Core.#destructorIsTriggered = true
102
+ Core.#destroyerIsTriggered = true
93
103
 
94
- signal && Core.log.info`${signal} ⇢ graceful shutdown initiated…`
104
+ signal
105
+ ? Core.log.info`graceful shutdown initiated ${signal}`
106
+ : Core.log.info`graceful shutdown initiated`
95
107
 
96
108
  const
97
- destructCores = [],
98
- destructRejects = []
109
+ destroyedCores = [],
110
+ destroyRejects = []
99
111
 
100
112
  for(const core of Core.#cores.values())
101
113
  {
102
- destructCores.push((async () =>
114
+ destroyedCores.push((async () =>
103
115
  {
104
116
  try
105
117
  {
106
- await core.destruct()
118
+ await core.destroy()
107
119
  }
108
120
  catch(error)
109
121
  {
110
- destructRejects.push(error)
122
+ destroyRejects.push(error)
111
123
  }
112
124
  })())
113
125
  }
114
126
 
115
- await Promise.all(destructCores)
127
+ await Promise.all(destroyedCores)
116
128
 
117
- if(destructRejects.length)
129
+ if(destroyRejects.length)
118
130
  {
119
131
  const error = new Error('Failed to shutdown gracefully')
120
- error.code = 'E_CORE_DESTRUCT_GRACEFUL'
121
- error.cause = destructRejects
132
+ error.code = 'E_CORE_DESTROY_GRACEFUL'
133
+ error.cause = destroyRejects
122
134
  Core.log.fail`${error}`
123
135
  setImmediate(() => process.exit(1))
124
136
  }
@@ -133,25 +145,25 @@ export default class Core
133
145
  }
134
146
  }
135
147
 
136
- async destruct()
148
+ async destroy()
137
149
  {
138
150
  // First remove the core instance from the static core registry
139
- // to prevent multiple destruct calls.
151
+ // to prevent multiple destroy calls.
140
152
  Core.#cores.delete(this)
141
153
 
142
- // Then destruct the core workers, if clustered, using a timeout.
154
+ // Then destroy the core workers, if clustered, using a timeout.
143
155
  const
144
- timeout = this.config.find('core/destruct/timeout', 15e3),
145
- timeoutError = new Error(`Failed to destruct core within ${(timeout/1e3).toFixed(1)}s`),
146
- destructTimeout = (ctx) => new Promise((_, reject) => ctx.id = setTimeout(() => reject(timeoutError), timeout)),
147
- destructWorkers = [],
148
- destructRejects = []
156
+ timeout = this.config.find('core/destroy/timeout', 15e3),
157
+ timeoutError = new Error(`Failed to destroy core within ${(timeout/1e3).toFixed(1)}s`),
158
+ destroyTimeout = (ctx) => new Promise((_, reject) => ctx.id = setTimeout(() => reject(timeoutError), timeout)),
159
+ destroyedWorkers = [],
160
+ destroyRejects = []
149
161
 
150
- timeoutError.code = 'E_CORE_DESTRUCT_TIMEOUT'
162
+ timeoutError.code = 'E_CORE_DESTROY_TIMEOUT'
151
163
 
152
164
  for(const id in this.#workers)
153
165
  {
154
- destructWorkers.push((async () =>
166
+ destroyedWorkers.push((async () =>
155
167
  {
156
168
  // Attempt to kill the worker.
157
169
  this.#workers[id].kill()
@@ -162,42 +174,42 @@ export default class Core
162
174
 
163
175
  try
164
176
  {
165
- if(destructWorkers.length)
177
+ if(destroyedWorkers.length)
166
178
  {
167
179
  const timeout = {}
168
- await Promise.race([ destructTimeout(timeout), Promise.all(destructWorkers) ])
180
+ await Promise.race([ destroyTimeout(timeout), Promise.all(destroyedWorkers) ])
169
181
  clearTimeout(timeout.id)
170
182
  }
171
183
  }
172
184
  catch(reason)
173
185
  {
174
- const error = new Error(`Failed to destruct workers`)
175
- error.code = 'E_CORE_DESTRUCT_WORKERS'
186
+ const error = new Error(`Failed to destroy workers`)
187
+ error.code = 'E_CORE_DESTROY_WORKERS'
176
188
  error.cause = reason
177
- destructRejects.push(error)
189
+ destroyRejects.push(error)
178
190
  }
179
191
 
180
- // Then destruct the core locator and all loaded services, restricted by a
192
+ // Then destroy the core locator and all loaded services, restricted by a
181
193
  // timeout if it takes to long.
182
194
  try
183
195
  {
184
196
  const timeout = {}
185
- await Promise.race([ destructTimeout(timeout), this.locate.destruct() ])
197
+ await Promise.race([ destroyTimeout(timeout), this.locate.destroy() ])
186
198
  clearTimeout(timeout.id)
187
199
  }
188
200
  catch(reason)
189
201
  {
190
- const error = new Error(`Failed to destruct locator`)
191
- error.code = 'E_CORE_DESTRUCT_LOCATOR'
202
+ const error = new Error(`Failed to destroy locator`)
203
+ error.code = 'E_CORE_DESTROY_LOCATOR'
192
204
  error.cause = reason
193
- destructRejects.push(error)
205
+ destroyRejects.push(error)
194
206
  }
195
207
 
196
- if(destructRejects.length)
208
+ if(destroyRejects.length)
197
209
  {
198
- const error = new Error(`Failed to destruct core gracefully`)
199
- error.code = 'E_CORE_DESTRUCT'
200
- error.cause = destructRejects
210
+ const error = new Error(`Failed to destroy core gracefully`)
211
+ error.code = 'E_CORE_DESTROY'
212
+ error.cause = destroyRejects
201
213
  throw error
202
214
  }
203
215
  }
@@ -212,8 +224,9 @@ export default class Core
212
224
 
213
225
  // Forward the base path for the scoped path-resolver
214
226
  // used by the locator and config services.
227
+ // OBS! this logic relies on that the locator and config
228
+ // services uses the same path-resolver.
215
229
  this.locate.pathResolver.basePath = basePath
216
- this.config.pathResolver.basePath = basePath
217
230
 
218
231
  this.#eventlog.push({ type: 'basePath', basePath })
219
232
  }
@@ -333,7 +346,7 @@ export default class Core
333
346
  this.#workers[forkId].once('exit', this.#reloadWorker.bind(this, forkId, forkBranch, forkVersion))
334
347
  this.#workers[forkId].sync = this.#createSynchoronizer(forkId)
335
348
 
336
- Core.log.info`clustered ${'CORE:' + forkId}`
349
+ Core.log.info`${'CORE:' + forkId} ⇡ clustered`
337
350
 
338
351
  try
339
352
  {
@@ -346,6 +359,8 @@ export default class Core
346
359
  error.cause = reason
347
360
  throw error
348
361
  }
362
+
363
+ Core.log.info`synchronized ${'CORE:' + forkId}`
349
364
  }
350
365
 
351
366
  return branch + forks
package/index.test.js CHANGED
@@ -92,6 +92,6 @@ suite('@superhero/core', () =>
92
92
  core.bootstrap(),
93
93
  'Should bootstrap without errors')
94
94
 
95
- await core.destruct()
95
+ await core.destroy()
96
96
  })
97
97
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superhero/core",
3
- "version": "4.0.0-beta.7",
3
+ "version": "4.0.1",
4
4
  "description": "Core functionalities for the superhero framework.",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
@@ -9,10 +9,8 @@
9
9
  ".": "./index.js"
10
10
  },
11
11
  "dependencies": {
12
- "@superhero/bootstrap": "^4.1.0",
13
- "@superhero/config": "^4.1.2",
14
- "@superhero/locator": "^4.1.2",
15
- "@superhero/log": "^4.0.0"
12
+ "@superhero/bootstrap": "^4.1.1",
13
+ "@superhero/locator": "^4.2.2"
16
14
  },
17
15
  "scripts": {
18
16
  "test": "node --trace-warnings --test --experimental-test-coverage"