@kapeta/local-cluster-service 0.6.0 → 0.7.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.
Files changed (193) hide show
  1. package/.eslintrc.cjs +17 -0
  2. package/.github/workflows/main.yml +22 -22
  3. package/.prettierignore +4 -0
  4. package/.vscode/launch.json +2 -4
  5. package/CHANGELOG.md +14 -0
  6. package/definitions.d.ts +17 -35
  7. package/dist/cjs/index.d.ts +27 -0
  8. package/dist/cjs/index.js +126 -0
  9. package/dist/cjs/package.json +1 -0
  10. package/dist/cjs/src/assetManager.d.ts +31 -0
  11. package/dist/cjs/src/assetManager.js +153 -0
  12. package/dist/cjs/src/assets/routes.d.ts +3 -0
  13. package/dist/cjs/src/assets/routes.js +117 -0
  14. package/dist/cjs/src/clusterService.d.ts +40 -0
  15. package/dist/cjs/src/clusterService.js +114 -0
  16. package/dist/cjs/src/codeGeneratorManager.d.ts +8 -0
  17. package/dist/cjs/src/codeGeneratorManager.js +53 -0
  18. package/dist/cjs/src/config/routes.d.ts +3 -0
  19. package/dist/cjs/src/config/routes.js +126 -0
  20. package/dist/cjs/src/configManager.d.ts +36 -0
  21. package/dist/cjs/src/configManager.js +110 -0
  22. package/dist/cjs/src/containerManager.d.ts +89 -0
  23. package/dist/cjs/src/containerManager.js +365 -0
  24. package/dist/cjs/src/filesystem/routes.d.ts +3 -0
  25. package/dist/cjs/src/filesystem/routes.js +69 -0
  26. package/dist/cjs/src/filesystemManager.d.ts +15 -0
  27. package/dist/cjs/src/filesystemManager.js +87 -0
  28. package/dist/cjs/src/identities/routes.d.ts +3 -0
  29. package/dist/cjs/src/identities/routes.js +18 -0
  30. package/dist/cjs/src/instanceManager.d.ts +56 -0
  31. package/dist/cjs/src/instanceManager.js +424 -0
  32. package/dist/cjs/src/instances/routes.d.ts +3 -0
  33. package/dist/cjs/src/instances/routes.js +134 -0
  34. package/dist/cjs/src/middleware/cors.d.ts +2 -0
  35. package/dist/cjs/src/middleware/cors.js +10 -0
  36. package/dist/cjs/src/middleware/kapeta.d.ts +11 -0
  37. package/dist/cjs/src/middleware/kapeta.js +17 -0
  38. package/dist/cjs/src/middleware/stringBody.d.ts +5 -0
  39. package/dist/cjs/src/middleware/stringBody.js +14 -0
  40. package/dist/cjs/src/networkManager.d.ts +32 -0
  41. package/dist/cjs/src/networkManager.js +109 -0
  42. package/dist/cjs/src/operatorManager.d.ts +36 -0
  43. package/dist/cjs/src/operatorManager.js +165 -0
  44. package/dist/cjs/src/progressListener.d.ts +20 -0
  45. package/dist/cjs/src/progressListener.js +91 -0
  46. package/dist/cjs/src/providerManager.d.ts +9 -0
  47. package/dist/cjs/src/providerManager.js +51 -0
  48. package/dist/cjs/src/providers/routes.d.ts +3 -0
  49. package/dist/cjs/src/providers/routes.js +42 -0
  50. package/dist/cjs/src/proxy/routes.d.ts +3 -0
  51. package/dist/cjs/src/proxy/routes.js +111 -0
  52. package/dist/cjs/src/proxy/types/rest.d.ts +4 -0
  53. package/dist/cjs/src/proxy/types/rest.js +114 -0
  54. package/dist/cjs/src/proxy/types/web.d.ts +4 -0
  55. package/dist/cjs/src/proxy/types/web.js +53 -0
  56. package/dist/cjs/src/repositoryManager.d.ts +17 -0
  57. package/dist/cjs/src/repositoryManager.js +215 -0
  58. package/dist/cjs/src/serviceManager.d.ts +29 -0
  59. package/dist/cjs/src/serviceManager.js +99 -0
  60. package/dist/cjs/src/socketManager.d.ts +14 -0
  61. package/dist/cjs/src/socketManager.js +53 -0
  62. package/dist/cjs/src/storageService.d.ts +17 -0
  63. package/dist/cjs/src/storageService.js +74 -0
  64. package/dist/cjs/src/traffic/routes.d.ts +3 -0
  65. package/dist/cjs/src/traffic/routes.js +18 -0
  66. package/dist/cjs/src/types.d.ts +88 -0
  67. package/dist/cjs/src/types.js +2 -0
  68. package/dist/cjs/src/utils/BlockInstanceRunner.d.ts +29 -0
  69. package/dist/cjs/src/utils/BlockInstanceRunner.js +468 -0
  70. package/dist/cjs/src/utils/LogData.d.ts +19 -0
  71. package/dist/cjs/src/utils/LogData.js +43 -0
  72. package/dist/cjs/src/utils/pathTemplateParser.d.ts +26 -0
  73. package/dist/cjs/src/utils/pathTemplateParser.js +121 -0
  74. package/dist/cjs/src/utils/utils.d.ts +1 -0
  75. package/dist/cjs/src/utils/utils.js +18 -0
  76. package/dist/cjs/start.d.ts +1 -0
  77. package/dist/cjs/start.js +12 -0
  78. package/dist/esm/index.d.ts +27 -0
  79. package/dist/esm/index.js +121 -0
  80. package/dist/esm/package.json +1 -0
  81. package/dist/esm/src/assetManager.d.ts +31 -0
  82. package/{src → dist/esm/src}/assetManager.js +22 -60
  83. package/dist/esm/src/assets/routes.d.ts +3 -0
  84. package/{src → dist/esm/src}/assets/routes.js +21 -36
  85. package/dist/esm/src/clusterService.d.ts +40 -0
  86. package/{src → dist/esm/src}/clusterService.js +14 -37
  87. package/dist/esm/src/codeGeneratorManager.d.ts +8 -0
  88. package/{src → dist/esm/src}/codeGeneratorManager.js +15 -24
  89. package/dist/esm/src/config/routes.d.ts +3 -0
  90. package/dist/esm/src/config/routes.js +121 -0
  91. package/dist/esm/src/configManager.d.ts +36 -0
  92. package/{src → dist/esm/src}/configManager.js +11 -40
  93. package/dist/esm/src/containerManager.d.ts +89 -0
  94. package/{src → dist/esm/src}/containerManager.js +81 -182
  95. package/dist/esm/src/filesystem/routes.d.ts +3 -0
  96. package/dist/esm/src/filesystem/routes.js +64 -0
  97. package/dist/esm/src/filesystemManager.d.ts +15 -0
  98. package/{src → dist/esm/src}/filesystemManager.js +20 -28
  99. package/dist/esm/src/identities/routes.d.ts +3 -0
  100. package/dist/esm/src/identities/routes.js +13 -0
  101. package/dist/esm/src/instanceManager.d.ts +56 -0
  102. package/{src → dist/esm/src}/instanceManager.js +94 -175
  103. package/dist/esm/src/instances/routes.d.ts +3 -0
  104. package/{src → dist/esm/src}/instances/routes.js +31 -70
  105. package/dist/esm/src/middleware/cors.d.ts +2 -0
  106. package/{src → dist/esm/src}/middleware/cors.js +2 -3
  107. package/dist/esm/src/middleware/kapeta.d.ts +11 -0
  108. package/{src → dist/esm/src}/middleware/kapeta.js +3 -7
  109. package/dist/esm/src/middleware/stringBody.d.ts +5 -0
  110. package/{src → dist/esm/src}/middleware/stringBody.js +2 -3
  111. package/dist/esm/src/networkManager.d.ts +32 -0
  112. package/{src → dist/esm/src}/networkManager.js +16 -33
  113. package/dist/esm/src/operatorManager.d.ts +36 -0
  114. package/{src → dist/esm/src}/operatorManager.js +35 -91
  115. package/dist/esm/src/progressListener.d.ts +20 -0
  116. package/dist/esm/src/progressListener.js +88 -0
  117. package/dist/esm/src/providerManager.d.ts +9 -0
  118. package/dist/esm/src/providerManager.js +45 -0
  119. package/dist/esm/src/providers/routes.d.ts +3 -0
  120. package/{src → dist/esm/src}/providers/routes.js +10 -16
  121. package/dist/esm/src/proxy/routes.d.ts +3 -0
  122. package/dist/esm/src/proxy/routes.js +106 -0
  123. package/dist/esm/src/proxy/types/rest.d.ts +4 -0
  124. package/dist/esm/src/proxy/types/rest.js +107 -0
  125. package/dist/esm/src/proxy/types/web.d.ts +4 -0
  126. package/{src → dist/esm/src}/proxy/types/web.js +13 -35
  127. package/dist/esm/src/repositoryManager.d.ts +17 -0
  128. package/dist/esm/src/repositoryManager.js +209 -0
  129. package/dist/esm/src/serviceManager.d.ts +29 -0
  130. package/{src → dist/esm/src}/serviceManager.js +12 -42
  131. package/dist/esm/src/socketManager.d.ts +14 -0
  132. package/{src → dist/esm/src}/socketManager.js +19 -23
  133. package/dist/esm/src/storageService.d.ts +17 -0
  134. package/{src → dist/esm/src}/storageService.js +8 -27
  135. package/dist/esm/src/traffic/routes.d.ts +3 -0
  136. package/{src → dist/esm/src}/traffic/routes.js +4 -9
  137. package/dist/esm/src/types.d.ts +88 -0
  138. package/dist/esm/src/types.js +1 -0
  139. package/dist/esm/src/utils/BlockInstanceRunner.d.ts +29 -0
  140. package/{src → dist/esm/src}/utils/BlockInstanceRunner.js +137 -256
  141. package/dist/esm/src/utils/LogData.d.ts +19 -0
  142. package/{src → dist/esm/src}/utils/LogData.js +11 -22
  143. package/dist/esm/src/utils/pathTemplateParser.d.ts +26 -0
  144. package/{src → dist/esm/src}/utils/pathTemplateParser.js +21 -40
  145. package/dist/esm/src/utils/utils.d.ts +1 -0
  146. package/dist/esm/src/utils/utils.js +11 -0
  147. package/dist/esm/start.d.ts +1 -0
  148. package/dist/esm/start.js +7 -0
  149. package/index.ts +147 -0
  150. package/package.json +106 -74
  151. package/src/assetManager.ts +191 -0
  152. package/src/assets/routes.ts +132 -0
  153. package/src/clusterService.ts +134 -0
  154. package/src/codeGeneratorManager.ts +57 -0
  155. package/src/config/routes.ts +159 -0
  156. package/src/configManager.ts +148 -0
  157. package/src/containerManager.ts +466 -0
  158. package/src/filesystem/routes.ts +74 -0
  159. package/src/filesystemManager.ts +93 -0
  160. package/src/identities/routes.ts +20 -0
  161. package/src/instanceManager.ts +503 -0
  162. package/src/instances/routes.ts +164 -0
  163. package/src/middleware/cors.ts +9 -0
  164. package/src/middleware/kapeta.ts +27 -0
  165. package/src/middleware/stringBody.ts +16 -0
  166. package/src/networkManager.ts +137 -0
  167. package/src/operatorManager.ts +221 -0
  168. package/src/progressListener.ts +102 -0
  169. package/src/{providerManager.js → providerManager.ts} +15 -31
  170. package/src/providers/routes.ts +46 -0
  171. package/src/proxy/routes.ts +148 -0
  172. package/src/proxy/types/{rest.js → rest.ts} +30 -30
  173. package/src/proxy/types/web.ts +60 -0
  174. package/src/{repositoryManager.js → repositoryManager.ts} +45 -73
  175. package/src/serviceManager.ts +120 -0
  176. package/src/socketManager.ts +57 -0
  177. package/src/storageService.ts +88 -0
  178. package/src/traffic/routes.ts +18 -0
  179. package/src/types.ts +97 -0
  180. package/src/utils/BlockInstanceRunner.ts +555 -0
  181. package/src/utils/LogData.ts +47 -0
  182. package/src/utils/pathTemplateParser.ts +138 -0
  183. package/src/utils/utils.ts +12 -0
  184. package/start.ts +8 -0
  185. package/tsconfig.json +13 -0
  186. package/index.js +0 -127
  187. package/src/config/routes.js +0 -160
  188. package/src/filesystem/routes.js +0 -74
  189. package/src/identities/routes.js +0 -19
  190. package/src/progressListener.js +0 -82
  191. package/src/proxy/routes.js +0 -126
  192. package/src/utils/utils.js +0 -13
  193. package/start.js +0 -7
@@ -1,92 +1,71 @@
1
- const _ = require('lodash');
2
- const request = require('request');
3
- const EventEmitter = require("events");
4
- const BlockInstanceRunner = require('./utils/BlockInstanceRunner');
5
-
6
- const storageService = require('./storageService');
7
- const socketManager = require('./socketManager');
8
- const serviceManager = require('./serviceManager');
9
- const assetManager = require('./assetManager');
10
- const containerManager = require('./containerManager');
11
- const configManager = require("./configManager");
12
-
1
+ import _ from 'lodash';
2
+ import request from 'request';
3
+ import EventEmitter from 'events';
4
+ import { BlockInstanceRunner } from './utils/BlockInstanceRunner';
5
+ import { storageService } from './storageService';
6
+ import { socketManager } from './socketManager';
7
+ import { serviceManager } from './serviceManager';
8
+ import { assetManager } from './assetManager';
9
+ import { containerManager } from './containerManager';
10
+ import { configManager } from './configManager';
13
11
  const CHECK_INTERVAL = 10000;
14
12
  const DEFAULT_HEALTH_PORT_TYPE = 'rest';
15
-
16
13
  const EVENT_STATUS_CHANGED = 'status-changed';
17
14
  const EVENT_INSTANCE_CREATED = 'instance-created';
18
15
  const EVENT_INSTANCE_EXITED = 'instance-exited';
19
16
  const EVENT_INSTANCE_LOG = 'instance-log';
20
-
21
17
  const STATUS_STARTING = 'starting';
22
18
  const STATUS_READY = 'ready';
23
19
  const STATUS_UNHEALTHY = 'unhealthy';
24
20
  const STATUS_STOPPED = 'stopped';
25
-
26
21
  const MIN_TIME_RUNNING = 30000; //If something didnt run for more than 30 secs - it failed
27
-
28
22
  class InstanceManager {
23
+ _interval;
24
+ /**
25
+ * Contains an array of running instances that have self-registered with this
26
+ * cluster service. This is done by the Kapeta SDKs
27
+ */
28
+ _instances = [];
29
+ /**
30
+ * Contains the process info for the instances started by this manager. In memory only
31
+ * so can't be relied on for knowing everything that's running.
32
+ *
33
+ */
34
+ _processes = {};
29
35
  constructor() {
30
36
  this._interval = setInterval(() => this._checkInstances(), CHECK_INTERVAL);
31
- /**
32
- * Contains an array of running instances that have self-registered with this
33
- * cluster service. This is done by the Kapeta SDKs
34
- *
35
- * @type {any[]}
36
- * @private
37
- */
38
37
  this._instances = storageService.section('instances', []);
39
- /**
40
- * Contains the process info for the instances started by this manager. In memory only
41
- * so can't be relied on for knowing everything that's running.
42
- *
43
- * @type {{[systemId:string]:{[instanceId:string]:ProcessInfo}}}
44
- * @private
45
- */
46
38
  this._processes = {};
47
-
48
39
  this._checkInstances();
49
40
  }
50
-
51
41
  _save() {
52
42
  storageService.put('instances', this._instances);
53
43
  }
54
-
55
44
  async _checkInstances() {
56
45
  let changed = false;
57
46
  for (let i = 0; i < this._instances.length; i++) {
58
47
  const instance = this._instances[i];
59
-
60
48
  const newStatus = await this._getInstanceStatus(instance);
61
-
62
- if (newStatus === STATUS_UNHEALTHY &&
63
- instance.status === STATUS_STARTING) {
49
+ if (newStatus === STATUS_UNHEALTHY && instance.status === STATUS_STARTING) {
64
50
  // If instance is starting we consider unhealthy an indication
65
51
  // that it is still starting
66
52
  continue;
67
53
  }
68
-
69
54
  if (instance.status !== newStatus) {
70
55
  instance.status = newStatus;
71
- console.log(
72
- 'Instance status changed: %s %s -> %s',
73
- instance.systemId, instance.instanceId, instance.status
74
- )
56
+ console.log('Instance status changed: %s %s -> %s', instance.systemId, instance.instanceId, instance.status);
75
57
  this._emit(instance.systemId, EVENT_STATUS_CHANGED, instance);
76
58
  changed = true;
77
59
  }
78
60
  }
79
-
80
61
  if (changed) {
81
62
  this._save();
82
63
  }
83
64
  }
84
-
85
65
  async _isRunning(instance) {
86
66
  if (!instance.pid) {
87
67
  return;
88
68
  }
89
-
90
69
  if (instance.type === 'docker') {
91
70
  const container = await containerManager.get(instance.pid);
92
71
  if (!container) {
@@ -95,64 +74,57 @@ class InstanceManager {
95
74
  }
96
75
  return await container.isRunning();
97
76
  }
98
-
99
77
  //Otherwise its just a normal process.
100
78
  //TODO: Handle for Windows
101
79
  try {
102
- return process.kill(instance.pid, 0)
103
- } catch (err) {
80
+ return process.kill(instance.pid, 0);
81
+ }
82
+ catch (err) {
104
83
  return err.code === 'EPERM';
105
84
  }
106
85
  }
107
-
108
86
  async _getInstanceStatus(instance) {
109
87
  if (instance.status === STATUS_STOPPED) {
110
88
  //Will only change when it reregisters
111
89
  return STATUS_STOPPED;
112
90
  }
113
-
114
- if (!await this._isRunning(instance)) {
91
+ if (!(await this._isRunning(instance))) {
115
92
  return STATUS_STOPPED;
116
93
  }
117
-
118
94
  if (!instance.health) {
119
95
  //No health url means we assume it's healthy as soon as it's running
120
96
  return STATUS_READY;
121
97
  }
122
-
123
98
  return new Promise((resolve) => {
99
+ if (!instance.health) {
100
+ resolve(STATUS_READY);
101
+ return;
102
+ }
124
103
  request(instance.health, (err, response) => {
125
104
  if (err) {
126
105
  resolve(STATUS_UNHEALTHY);
127
106
  return;
128
107
  }
129
-
130
- if (response.responseCode > 399) {
108
+ if (response.statusCode > 399) {
131
109
  resolve(STATUS_UNHEALTHY);
132
110
  return;
133
111
  }
134
-
135
112
  resolve(STATUS_READY);
136
113
  });
137
114
  });
138
115
  }
139
-
140
116
  getInstances() {
141
117
  if (!this._instances) {
142
118
  return [];
143
119
  }
144
-
145
120
  return [...this._instances];
146
121
  }
147
-
148
122
  getInstancesForPlan(systemId) {
149
123
  if (!this._instances) {
150
124
  return [];
151
125
  }
152
-
153
- return this._instances.filter(instance => instance.systemId === systemId);
126
+ return this._instances.filter((instance) => instance.systemId === systemId);
154
127
  }
155
-
156
128
  /**
157
129
  * Get instance information
158
130
  *
@@ -161,26 +133,19 @@ class InstanceManager {
161
133
  * @return {*}
162
134
  */
163
135
  getInstance(systemId, instanceId) {
164
- return _.find(this._instances, {systemId, instanceId});
136
+ return _.find(this._instances, { systemId, instanceId });
165
137
  }
166
-
167
138
  /**
168
139
  *
169
140
  * @param {string} systemId
170
141
  * @param {string} instanceId
171
- * @param {{health:string,pid:string,type:'docker'|'local',portType?:string}} info
142
+ * @param {InstanceInfo} info
172
143
  * @return {Promise<void>}
173
144
  */
174
145
  async registerInstance(systemId, instanceId, info) {
175
146
  let instance = this.getInstance(systemId, instanceId);
176
-
177
147
  //Get target address
178
- let address = await serviceManager.getProviderAddress(
179
- systemId,
180
- instanceId,
181
- info.portType ?? DEFAULT_HEALTH_PORT_TYPE
182
- );
183
-
148
+ let address = await serviceManager.getProviderAddress(systemId, instanceId, info.portType ?? DEFAULT_HEALTH_PORT_TYPE);
184
149
  let healthUrl = null;
185
150
  let health = info.health;
186
151
  if (health) {
@@ -189,7 +154,6 @@ class InstanceManager {
189
154
  }
190
155
  healthUrl = address + health;
191
156
  }
192
-
193
157
  if (instance) {
194
158
  instance.status = STATUS_STARTING;
195
159
  instance.pid = info.pid;
@@ -201,7 +165,8 @@ class InstanceManager {
201
165
  instance.health = healthUrl;
202
166
  }
203
167
  this._emit(systemId, EVENT_STATUS_CHANGED, instance);
204
- } else {
168
+ }
169
+ else {
205
170
  instance = {
206
171
  systemId,
207
172
  instanceId,
@@ -209,19 +174,15 @@ class InstanceManager {
209
174
  pid: info.pid,
210
175
  type: info.type,
211
176
  health: healthUrl,
212
- address
177
+ address,
213
178
  };
214
-
215
179
  this._instances.push(instance);
216
-
217
180
  this._emit(systemId, EVENT_INSTANCE_CREATED, instance);
218
181
  }
219
-
220
182
  this._save();
221
183
  }
222
-
223
184
  setInstanceAsStopped(systemId, instanceId) {
224
- const instance = _.find(this._instances, {systemId, instanceId});
185
+ const instance = _.find(this._instances, { systemId, instanceId });
225
186
  if (instance) {
226
187
  instance.status = STATUS_STOPPED;
227
188
  instance.pid = null;
@@ -230,209 +191,171 @@ class InstanceManager {
230
191
  this._save();
231
192
  }
232
193
  }
233
-
234
194
  _emit(systemId, type, payload) {
235
- socketManager.emit(`${systemId}/instances`, type, payload);
195
+ try {
196
+ socketManager.emit(`${systemId}/instances`, type, payload);
197
+ }
198
+ catch (e) {
199
+ console.warn('Failed to emit instance event: %s', e.message);
200
+ }
236
201
  }
237
-
238
- /**
239
- *
240
- * @param planRef
241
- * @return {Promise<ProcessInfo[]>}
242
- */
243
202
  async createProcessesForPlan(planRef) {
244
203
  await this.stopAllForPlan(planRef);
245
-
246
204
  const plan = await assetManager.getPlan(planRef, true);
247
205
  if (!plan) {
248
206
  throw new Error('Plan not found: ' + planRef);
249
207
  }
250
-
251
208
  if (!plan.spec.blocks) {
252
209
  console.warn('No blocks found in plan', planRef);
253
210
  return [];
254
211
  }
255
-
256
212
  let promises = [];
257
213
  let errors = [];
258
- for(let blockInstance of Object.values(plan.spec.blocks)) {
214
+ for (let blockInstance of Object.values(plan.spec.blocks)) {
259
215
  try {
260
216
  promises.push(this.createProcess(planRef, blockInstance.id));
261
- } catch (e) {
217
+ }
218
+ catch (e) {
262
219
  errors.push(e);
263
220
  }
264
221
  }
265
-
266
222
  const settled = await Promise.allSettled(promises);
267
-
268
223
  if (errors.length > 0) {
269
224
  throw errors[0];
270
225
  }
271
-
272
- return settled.map(p => p.value);
226
+ return settled.map((p) => (p.status === 'fulfilled' ? p.value : null)).filter((p) => !!p);
273
227
  }
274
-
275
228
  async _stopInstance(instance) {
276
229
  if (!instance.pid) {
277
230
  return;
278
231
  }
279
-
280
232
  if (instance.status === 'stopped') {
281
233
  return;
282
234
  }
283
-
284
235
  try {
285
236
  if (instance.type === 'docker') {
286
237
  const container = await containerManager.get(instance.pid);
287
238
  if (container) {
288
239
  try {
289
240
  await container.stop();
290
- } catch (e) {
241
+ }
242
+ catch (e) {
291
243
  console.error('Failed to stop container', e);
292
244
  }
293
245
  }
294
246
  return;
295
247
  }
296
248
  process.kill(instance.pid, 'SIGTERM');
297
- } catch (e) {
249
+ }
250
+ catch (e) {
298
251
  console.error('Failed to stop process', e);
299
252
  }
300
253
  }
301
-
302
254
  async stopAllForPlan(planRef) {
303
-
304
255
  if (this._processes[planRef]) {
305
256
  const promises = [];
306
257
  console.log('Stopping all processes for plan', planRef);
307
- for(let instance of Object.values(this._processes[planRef])) {
258
+ for (let instance of Object.values(this._processes[planRef])) {
308
259
  promises.push(instance.stop());
309
260
  }
310
-
311
261
  await Promise.all(promises);
312
-
313
262
  this._processes[planRef] = {};
314
263
  }
315
-
316
264
  //Also stop instances not being maintained by the cluster service
317
- const instancesForPlan = this._instances
318
- .filter(instance => instance.systemId === planRef);
319
-
265
+ const instancesForPlan = this._instances.filter((instance) => instance.systemId === planRef);
320
266
  const promises = [];
321
- for(let instance of instancesForPlan) {
267
+ for (let instance of instancesForPlan) {
322
268
  promises.push(this._stopInstance(instance));
323
269
  }
324
-
325
270
  await Promise.all(promises);
326
271
  }
327
-
328
- /**
329
- *
330
- * @param planRef
331
- * @param instanceId
332
- * @return {Promise<PromiseInfo>}
333
- */
334
272
  async createProcess(planRef, instanceId) {
335
273
  const plan = await assetManager.getPlan(planRef, true);
336
274
  if (!plan) {
337
275
  throw new Error('Plan not found: ' + planRef);
338
276
  }
339
-
340
- const blockInstance = plan.spec && plan.spec.blocks ? _.find(plan.spec.blocks, {id: instanceId}) : null;
277
+ const blockInstance = plan.spec && plan.spec.blocks ? _.find(plan.spec.blocks, { id: instanceId }) : null;
341
278
  if (!blockInstance) {
342
279
  throw new Error('Block instance not found: ' + instanceId);
343
280
  }
344
-
345
281
  const blockRef = blockInstance.block.ref;
346
-
347
282
  const blockAsset = await assetManager.getAsset(blockRef, true);
348
283
  const instanceConfig = await configManager.getConfigForSection(planRef, instanceId);
349
-
350
284
  if (!blockAsset) {
351
285
  throw new Error('Block not found: ' + blockRef);
352
286
  }
353
-
354
287
  if (!this._processes[planRef]) {
355
288
  this._processes[planRef] = {};
356
289
  }
357
-
358
290
  await this.stopProcess(planRef, instanceId);
359
291
  const type = blockAsset.version === 'local' ? 'local' : 'docker';
360
-
361
292
  const runner = new BlockInstanceRunner(planRef);
362
-
363
293
  const startTime = Date.now();
364
294
  try {
365
295
  const process = await runner.start(blockRef, instanceId, instanceConfig);
366
296
  //emit stdout/stderr via sockets
367
- process.output.on("data", (data) => {
297
+ process.output.on('data', (data) => {
368
298
  const payload = {
369
- source: "stdout",
370
- level: "INFO",
299
+ source: 'stdout',
300
+ level: 'INFO',
371
301
  message: data.toString(),
372
- time: Date.now()
302
+ time: Date.now(),
373
303
  };
374
304
  this._emit(instanceId, EVENT_INSTANCE_LOG, payload);
375
305
  });
376
-
377
306
  process.output.on('exit', (exitCode) => {
378
307
  const timeRunning = Date.now() - startTime;
379
308
  const instance = this.getInstance(planRef, instanceId);
380
- if (instance.status === STATUS_READY) {
309
+ if (instance?.status === STATUS_READY) {
381
310
  //It's already been running
382
311
  return;
383
312
  }
384
-
385
- if (exitCode === 143 ||
386
- exitCode === 137) {
313
+ if (exitCode === 143 || exitCode === 137) {
387
314
  //Process got SIGTERM (143) or SIGKILL (137)
388
315
  //TODO: Windows?
389
316
  return;
390
317
  }
391
-
392
318
  if (exitCode !== 0 || timeRunning < MIN_TIME_RUNNING) {
393
319
  this._emit(blockInstance.id, EVENT_INSTANCE_EXITED, {
394
- error: "Failed to start instance",
320
+ error: 'Failed to start instance',
395
321
  status: EVENT_INSTANCE_EXITED,
396
- instanceId: blockInstance.id
322
+ instanceId: blockInstance.id,
397
323
  });
398
324
  }
399
325
  });
400
-
401
326
  await this.registerInstance(planRef, instanceId, {
402
327
  type: process.type,
403
- pid: process.pid,
328
+ pid: process.pid ?? -1,
404
329
  health: null,
405
330
  portType: process.portType,
331
+ status: STATUS_STARTING,
406
332
  });
407
-
408
- return this._processes[planRef][instanceId] = process;
409
- } catch (e) {
333
+ return (this._processes[planRef][instanceId] = process);
334
+ }
335
+ catch (e) {
410
336
  console.warn('Failed to start instance', e);
411
337
  const logs = [
412
338
  {
413
- source: "stdout",
414
- level: "ERROR",
339
+ source: 'stdout',
340
+ level: 'ERROR',
415
341
  message: e.message,
416
- time: Date.now()
417
- }
342
+ time: Date.now(),
343
+ },
418
344
  ];
419
-
420
345
  await this.registerInstance(planRef, instanceId, {
421
346
  type: 'local',
422
347
  pid: null,
423
348
  health: null,
424
349
  portType: DEFAULT_HEALTH_PORT_TYPE,
350
+ status: STATUS_UNHEALTHY,
425
351
  });
426
-
427
352
  this._emit(instanceId, EVENT_INSTANCE_LOG, logs[0]);
428
-
429
353
  this._emit(blockInstance.id, EVENT_INSTANCE_EXITED, {
430
354
  error: `Failed to start instance: ${e.message}`,
431
355
  status: EVENT_INSTANCE_EXITED,
432
- instanceId: blockInstance.id
356
+ instanceId: blockInstance.id,
433
357
  });
434
-
435
- return this._processes[planRef][instanceId] = {
358
+ return (this._processes[planRef][instanceId] = {
436
359
  pid: -1,
437
360
  type,
438
361
  logs: () => logs,
@@ -440,12 +363,10 @@ class InstanceManager {
440
363
  ref: blockRef,
441
364
  id: instanceId,
442
365
  name: blockInstance.name,
443
- output: new EventEmitter()
444
- };
366
+ output: new EventEmitter(),
367
+ });
445
368
  }
446
-
447
369
  }
448
-
449
370
  /**
450
371
  *
451
372
  * @param {string} planRef
@@ -456,44 +377,42 @@ class InstanceManager {
456
377
  if (!this._processes[planRef]) {
457
378
  return null;
458
379
  }
459
-
460
380
  return this._processes[planRef][instanceId];
461
381
  }
462
-
382
+ async restartIfRunning(planRef, instanceId) {
383
+ if (!this._processes[planRef] || !this._processes[planRef][instanceId]) {
384
+ return;
385
+ }
386
+ // createProcess will stop the process first if it's running
387
+ return this.createProcess(planRef, instanceId);
388
+ }
463
389
  async stopProcess(planRef, instanceId) {
464
390
  if (!this._processes[planRef]) {
465
391
  return;
466
392
  }
467
-
468
393
  if (this._processes[planRef][instanceId]) {
469
394
  try {
470
395
  await this._processes[planRef][instanceId].stop();
471
- } catch (e) {
396
+ }
397
+ catch (e) {
472
398
  console.error('Failed to stop process for instance: %s -> %s', planRef, instanceId, e);
473
399
  }
474
400
  delete this._processes[planRef][instanceId];
475
401
  }
476
402
  }
477
-
478
403
  async stopAllProcesses() {
479
- for(let processesForPlan of Object.values(this._processes)) {
480
- for(let processInfo of Object.values(processesForPlan)) {
404
+ for (let processesForPlan of Object.values(this._processes)) {
405
+ for (let processInfo of Object.values(processesForPlan)) {
481
406
  await processInfo.stop();
482
407
  }
483
408
  }
484
409
  this._processes = {};
485
-
486
- for(let instance of this._instances) {
410
+ for (let instance of this._instances) {
487
411
  await this._stopInstance(instance);
488
412
  }
489
413
  }
490
414
  }
491
-
492
-
493
- const instanceManager = new InstanceManager();
494
-
415
+ export const instanceManager = new InstanceManager();
495
416
  process.on('exit', async () => {
496
417
  await instanceManager.stopAllProcesses();
497
418
  });
498
-
499
- module.exports = instanceManager;
@@ -0,0 +1,3 @@
1
+ /// <reference types="express" />
2
+ declare const router: import("express").Router;
3
+ export default router;