@ti-engine/core 1.2.4 → 1.3.3
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/CHANGELOG.md +44 -0
- package/README.md +7 -9
- package/bin/localization/labels.json +94 -60
- package/bin/start-instance.js +1 -1
- package/components/auditing.js +14 -13
- package/components/connection-observer.js +19 -4
- package/components/exchange/message-exchange.js +16 -1
- package/components/exchange/message-handler.js +37 -7
- package/components/exchange/message-observer.js +51 -4
- package/components/exchange/message-receiver.js +1 -1
- package/components/service-caller.js +248 -147
- package/components/service-executor.js +19 -4
- package/components/service-instance.js +8 -3
- package/integrations/redis-integration.js +86 -23
- package/package.json +1 -1
- package/utils/cache.js +24 -2
- package/utils/config.js +5 -5
- package/utils/exceptions.js +41 -35
- package/utils/localization.js +249 -12
- package/utils/logger.js +3 -3
- package/utils/tools.js +2 -2
|
@@ -48,15 +48,217 @@ const messageDispatcher = require( "#message-dispatcher" );
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* @typedef {Object} ServiceCallResult
|
|
51
|
-
* @property {
|
|
51
|
+
* @property {Exception|undefined} exception If there was exception during the service call processing, it will be set here. Otherwise, it will be 'undefined'.
|
|
52
52
|
* @property {boolean} isSuccessful A flag indicating if this service call can be considered successful or not.
|
|
53
|
-
* @property {Object|string|undefined} payload The payload containing the results from the service call processing. If string it is ID of the payload in the memory cache instead.
|
|
53
|
+
* @property {Object|string|undefined} payload The payload containing the results from the service call processing. If a string, it is ID of the payload in the memory cache instead.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Used to assemble and prepare a new {@link ServiceCall} object.
|
|
58
|
+
*
|
|
59
|
+
* @method
|
|
60
|
+
* @param {string} messageID The message ID of the service call. This has to be unique across the whole service call tree, including the current service call, and will be used to identify the service call in the service call tree.
|
|
61
|
+
* @param {ServiceAddress} serviceAddress The service address has to define a valid service domain name, service alias, and optionally a service version.
|
|
62
|
+
* @param {Object} serviceParams Set of named parameters to provide to the called service.
|
|
63
|
+
* @param {ServiceExecContext} serviceExecContext The context in which the service call is being executed.
|
|
64
|
+
* @returns {Promise<ServiceCall>}
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
let prepareServiceCall = ( messageID, serviceAddress, serviceParams, serviceExecContext ) => {
|
|
68
|
+
return new Promise( ( resolve ) => {
|
|
69
|
+
const ServiceInstance = require( "#service-instance" );
|
|
70
|
+
|
|
71
|
+
// assemble the new service call:
|
|
72
|
+
let chainID = ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.chainID : tools.getUUID();
|
|
73
|
+
let chainLevel = ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.chainLevel + 1 : 0;
|
|
74
|
+
let source = {
|
|
75
|
+
instanceID: ServiceInstance.instanceID,
|
|
76
|
+
route: ServiceInstance.serviceDomainName
|
|
77
|
+
};
|
|
78
|
+
let destination = {
|
|
79
|
+
instanceID: undefined,
|
|
80
|
+
route: serviceAddress.serviceDomainName
|
|
81
|
+
};
|
|
82
|
+
/** @type ServiceCall */
|
|
83
|
+
let serviceCall = {
|
|
84
|
+
authToken: serviceExecContext.authToken,
|
|
85
|
+
chainID: chainID,
|
|
86
|
+
chainLevel: chainLevel,
|
|
87
|
+
createdOn: Date.now(),
|
|
88
|
+
destination: destination,
|
|
89
|
+
executionTime: 0,
|
|
90
|
+
exception: undefined,
|
|
91
|
+
finishedOn: undefined,
|
|
92
|
+
isCompleted: false,
|
|
93
|
+
isSuccessful: undefined,
|
|
94
|
+
messageID: messageID,
|
|
95
|
+
payload: undefined,
|
|
96
|
+
predecessor: ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.messageID : undefined,
|
|
97
|
+
serviceAddress: serviceAddress,
|
|
98
|
+
serviceParams: serviceParams,
|
|
99
|
+
source: source,
|
|
100
|
+
successors: undefined
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
resolve( serviceCall );
|
|
104
|
+
} );
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Used to verify if the service is registered in the service registry.
|
|
109
|
+
*
|
|
110
|
+
* @method
|
|
111
|
+
* @param {ServiceAddress} serviceAddress
|
|
112
|
+
* @returns {Promise}
|
|
113
|
+
* @private
|
|
54
114
|
*/
|
|
115
|
+
let findServiceInRegistry = ( serviceAddress ) => {
|
|
116
|
+
return new Promise( ( resolve, reject ) => {
|
|
117
|
+
let serviceCatalog = config.getSetting( config.setting.SERVICE_REGISTRY_ADDRESS ) + serviceAddress.serviceDomainName;
|
|
118
|
+
cache.instance.isSetMember( serviceCatalog, serviceAddress.serviceAlias ).then( ( result ) => {
|
|
119
|
+
if ( result === true ) {
|
|
120
|
+
resolve();
|
|
121
|
+
} else {
|
|
122
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_COM_SERVICE_NOT_REGISTERED ) );
|
|
123
|
+
}
|
|
124
|
+
} ).catch( ( error ) => {
|
|
125
|
+
reject( exceptions.raise( error ) );
|
|
126
|
+
} );
|
|
127
|
+
} );
|
|
128
|
+
}
|
|
55
129
|
|
|
56
130
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
131
|
+
* A class defining a service call processor.
|
|
132
|
+
*
|
|
133
|
+
* @class ServiceCallProcessor
|
|
134
|
+
* @private
|
|
59
135
|
*/
|
|
136
|
+
class ServiceCallProcessor {
|
|
137
|
+
|
|
138
|
+
#messageID;
|
|
139
|
+
#serviceAddress;
|
|
140
|
+
#serviceParams;
|
|
141
|
+
#serviceExecContext;
|
|
142
|
+
#timeoutHandle;
|
|
143
|
+
#taskCompletionHandler;
|
|
144
|
+
#isProcessed = false;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @constructor
|
|
148
|
+
* @param {ServiceAddress} serviceAddress The service address has to define a valid service domain name, service alias, and optionally a service version.
|
|
149
|
+
* @param {Object} serviceParams Set of named parameters to provide to the called service.
|
|
150
|
+
* @param {ServiceExecContext} serviceExecContext The context in which the service call is being executed.
|
|
151
|
+
* @returns {ServiceCallProcessor}
|
|
152
|
+
*/
|
|
153
|
+
constructor( serviceAddress, serviceParams, serviceExecContext ) {
|
|
154
|
+
this.#messageID = tools.getUUID();
|
|
155
|
+
this.#serviceAddress = serviceAddress;
|
|
156
|
+
this.#serviceParams = serviceParams;
|
|
157
|
+
this.#serviceExecContext = serviceExecContext;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* Public interface */
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* The unique identifier of the service call.
|
|
164
|
+
*
|
|
165
|
+
* @property
|
|
166
|
+
* @returns {string}
|
|
167
|
+
* @public
|
|
168
|
+
*/
|
|
169
|
+
get messageID() {
|
|
170
|
+
return this.#messageID;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Used to start the execution of the service call.
|
|
175
|
+
* <br/>
|
|
176
|
+
* NOTE: This method will time out after specific preconfigured time, in which case it will resolve with {@link E_COM_SERVICE_EXEC_TIMEOUT} error.
|
|
177
|
+
*
|
|
178
|
+
* @method
|
|
179
|
+
* @returns {Promise<ServiceCallResult>}
|
|
180
|
+
* @public
|
|
181
|
+
*/
|
|
182
|
+
process() {
|
|
183
|
+
return Promise.race( [ this.#execute(), this.#timeout() ] ).then( ( result ) => {
|
|
184
|
+
clearTimeout( this.#timeoutHandle );
|
|
185
|
+
this.#isProcessed = true;
|
|
186
|
+
return result;
|
|
187
|
+
} ).catch( ( error ) => {
|
|
188
|
+
clearTimeout( this.#timeoutHandle );
|
|
189
|
+
this.#isProcessed = true;
|
|
190
|
+
logger.log( `Error during service call execution!`, logger.logSeverity.ERROR, error );
|
|
191
|
+
return {
|
|
192
|
+
isSuccessful: false,
|
|
193
|
+
exception: exceptions.raise( error ),
|
|
194
|
+
payload: undefined
|
|
195
|
+
};
|
|
196
|
+
} );
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Used to complete the execution of the service call that was started within the {@link process} method.
|
|
201
|
+
*
|
|
202
|
+
* @method
|
|
203
|
+
* @param {ServiceCall} serviceCall
|
|
204
|
+
* @public
|
|
205
|
+
*/
|
|
206
|
+
complete( serviceCall ) {
|
|
207
|
+
if ( this.#isProcessed !== true ) {
|
|
208
|
+
let serviceCallResult = {
|
|
209
|
+
exception: serviceCall.exception,
|
|
210
|
+
isSuccessful: ( serviceCall.isSuccessful !== undefined ) ? tools.toBool( serviceCall.isSuccessful ) : true,
|
|
211
|
+
payload: serviceCall.payload
|
|
212
|
+
};
|
|
213
|
+
this.#taskCompletionHandler( serviceCallResult );
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* Private interface */
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Used to execute the service call.
|
|
221
|
+
*
|
|
222
|
+
* @method
|
|
223
|
+
* @returns {Promise<ServiceCallResult>}
|
|
224
|
+
* @private
|
|
225
|
+
*/
|
|
226
|
+
#execute() {
|
|
227
|
+
return new Promise( ( resolve, reject ) => {
|
|
228
|
+
findServiceInRegistry( this.#serviceAddress ).then( () => {
|
|
229
|
+
return prepareServiceCall( this.#messageID, this.#serviceAddress, this.#serviceParams, this.#serviceExecContext );
|
|
230
|
+
} ).then( ( serviceCall ) => {
|
|
231
|
+
return messageDispatcher.instance.sendRequest( serviceCall );
|
|
232
|
+
} ).then( () => {
|
|
233
|
+
this.#taskCompletionHandler = ( serviceCallResult ) => {
|
|
234
|
+
resolve( serviceCallResult );
|
|
235
|
+
};
|
|
236
|
+
} ).catch( ( error ) => {
|
|
237
|
+
if ( this.#isProcessed !== true ) {
|
|
238
|
+
reject( exceptions.raise( error ) );
|
|
239
|
+
}
|
|
240
|
+
} );
|
|
241
|
+
} );
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Used to time out the service call execution.
|
|
246
|
+
*
|
|
247
|
+
* @method
|
|
248
|
+
* @returns {Promise<ServiceCallResult>}
|
|
249
|
+
* @private
|
|
250
|
+
*/
|
|
251
|
+
#timeout() {
|
|
252
|
+
return new Promise( ( resolve, reject ) => {
|
|
253
|
+
this.#timeoutHandle = setTimeout( () => {
|
|
254
|
+
if ( this.#isProcessed !== true ) {
|
|
255
|
+
reject( exceptions.raise( exceptions.exceptionCode.E_COM_SERVICE_EXEC_TIMEOUT ) );
|
|
256
|
+
}
|
|
257
|
+
}, config.getSetting( config.setting.SERVICE_EXECUTION_TIMEOUT ) );
|
|
258
|
+
} );
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
}
|
|
60
262
|
|
|
61
263
|
/**
|
|
62
264
|
* A class defining a service caller behavior.
|
|
@@ -67,13 +269,13 @@ const messageDispatcher = require( "#message-dispatcher" );
|
|
|
67
269
|
*/
|
|
68
270
|
class ServiceCaller extends MessageObserver {
|
|
69
271
|
|
|
70
|
-
#
|
|
272
|
+
#serviceCallProcessors = {};
|
|
71
273
|
|
|
72
274
|
/**
|
|
73
275
|
* @constructor
|
|
74
276
|
*/
|
|
75
277
|
constructor() {
|
|
76
|
-
super();
|
|
278
|
+
super( 10 );
|
|
77
279
|
}
|
|
78
280
|
|
|
79
281
|
/* Public interface */
|
|
@@ -91,44 +293,14 @@ class ServiceCaller extends MessageObserver {
|
|
|
91
293
|
* @public
|
|
92
294
|
*/
|
|
93
295
|
executeServiceCall( serviceAddress, serviceParams, serviceExecContext ) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
this.#addTaskHandler( messageID, ( serviceCall ) => {
|
|
101
|
-
this.#completeServiceCall( serviceCall ).then( ( serviceCall ) => {
|
|
102
|
-
let serviceCallResult = {
|
|
103
|
-
exception: serviceCall.exception,
|
|
104
|
-
isSuccessful: ( serviceCall.isSuccessful !== undefined ) ? serviceCall.isSuccessful : true,
|
|
105
|
-
payload: serviceCall.payload
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
resolve( serviceCallResult );
|
|
109
|
-
} ).catch( ( error ) => {
|
|
110
|
-
reject( exceptions.raise( error ) );
|
|
111
|
-
} );
|
|
112
|
-
} );
|
|
113
|
-
} ).catch( ( error ) => {
|
|
114
|
-
reject( exceptions.raise( error ) );
|
|
296
|
+
return new Promise( ( resolve ) => {
|
|
297
|
+
let processor = new ServiceCallProcessor( serviceAddress, serviceParams, serviceExecContext );
|
|
298
|
+
this.#addProcessor( processor.messageID, processor );
|
|
299
|
+
processor.process().then( ( serviceCallResult ) => {
|
|
300
|
+
this.#removeProcessor( processor.messageID );
|
|
301
|
+
resolve( serviceCallResult );
|
|
115
302
|
} );
|
|
116
303
|
} );
|
|
117
|
-
let timeoutHandle;
|
|
118
|
-
let timeout = new Promise( ( resolve, reject ) => {
|
|
119
|
-
timeoutHandle = setTimeout( () => reject( exceptions.raise( exceptions.exceptionCode.E_COM_SERVICE_EXEC_TIMEOUT ) ), config.getSetting( config.setting.SERVICE_EXECUTION_TIMEOUT ) );
|
|
120
|
-
} );
|
|
121
|
-
|
|
122
|
-
return Promise.race( [ execution, timeout ] ).then( ( result ) => {
|
|
123
|
-
clearTimeout( timeoutHandle );
|
|
124
|
-
return result;
|
|
125
|
-
} ).catch( ( error ) => {
|
|
126
|
-
logger.log( `Error during service call execution!`, logger.logSeverity.ERROR, error );
|
|
127
|
-
return {
|
|
128
|
-
isSuccessful: false,
|
|
129
|
-
exception: exceptions.raise( error )
|
|
130
|
-
};
|
|
131
|
-
} );
|
|
132
304
|
}
|
|
133
305
|
|
|
134
306
|
/**
|
|
@@ -136,18 +308,26 @@ class ServiceCaller extends MessageObserver {
|
|
|
136
308
|
*
|
|
137
309
|
* @method
|
|
138
310
|
* @param {string} identifier The identifier of the observed connection.
|
|
139
|
-
* @param {
|
|
311
|
+
* @param {ServiceCall} serviceCall The service call message for processing.
|
|
312
|
+
* @returns {ServiceCall} The service call message that was received.
|
|
140
313
|
* @override
|
|
141
314
|
* @public
|
|
142
315
|
*/
|
|
143
|
-
onMessage( identifier,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
316
|
+
onMessage( identifier, serviceCall ) {
|
|
317
|
+
// Complete the service call:
|
|
318
|
+
serviceCall.finishedOn = Date.now();
|
|
319
|
+
serviceCall.executionTime = serviceCall.finishedOn - serviceCall.createdOn;
|
|
320
|
+
serviceCall.isCompleted = true;
|
|
321
|
+
|
|
322
|
+
let processor = this.#getProcessor( serviceCall.messageID );
|
|
323
|
+
if ( processor ) {
|
|
324
|
+
this.#removeProcessor( serviceCall.messageID );
|
|
325
|
+
processor.complete( serviceCall );
|
|
148
326
|
} else {
|
|
149
|
-
logger.log( `Received message with ID '${
|
|
327
|
+
logger.log( `Received service call message with ID '${ serviceCall.messageID }' without registered processor! This may be caused by a service call timeout.`, logger.logSeverity.DEBUG, serviceCall.exception || undefined );
|
|
150
328
|
}
|
|
329
|
+
|
|
330
|
+
return serviceCall;
|
|
151
331
|
}
|
|
152
332
|
|
|
153
333
|
/**
|
|
@@ -174,133 +354,54 @@ class ServiceCaller extends MessageObserver {
|
|
|
174
354
|
super.onConnectionRecovered( identifier );
|
|
175
355
|
}
|
|
176
356
|
|
|
177
|
-
/* Private interface */
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Used to verify if the service is registered in the service registry.
|
|
181
|
-
*
|
|
182
|
-
* @method
|
|
183
|
-
* @param {ServiceAddress} serviceAddress
|
|
184
|
-
* @returns {Promise}
|
|
185
|
-
* @private
|
|
186
|
-
*/
|
|
187
|
-
#findServiceInRegistry( serviceAddress ) {
|
|
188
|
-
return new Promise( ( resolve, reject ) => {
|
|
189
|
-
let serviceCatalog = config.getSetting( config.setting.SERVICE_REGISTRY_ADDRESS ) + serviceAddress.serviceDomainName;
|
|
190
|
-
cache.instance.isSetMember( serviceCatalog, serviceAddress.serviceAlias ).then( ( result ) => {
|
|
191
|
-
if ( result === true ) {
|
|
192
|
-
resolve();
|
|
193
|
-
} else {
|
|
194
|
-
reject( exceptions.raise( exceptions.exceptionCode.E_COM_SERVICE_NOT_REGISTERED ) );
|
|
195
|
-
}
|
|
196
|
-
} ).catch( ( error ) => {
|
|
197
|
-
reject( exceptions.raise( error ) );
|
|
198
|
-
} );
|
|
199
|
-
} );
|
|
200
|
-
}
|
|
201
|
-
|
|
202
357
|
/**
|
|
203
|
-
*
|
|
358
|
+
* Needs to be invoked by the connection handler when the connection is irrevocably lost.
|
|
204
359
|
*
|
|
205
360
|
* @method
|
|
206
|
-
* @param {
|
|
207
|
-
* @
|
|
208
|
-
* @
|
|
209
|
-
* @returns {Promise<ServiceCall>}
|
|
210
|
-
* @private
|
|
361
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
362
|
+
* @override
|
|
363
|
+
* @public
|
|
211
364
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const ServiceInstance = require( "#service-instance" );
|
|
215
|
-
|
|
216
|
-
// assemble the new service call:
|
|
217
|
-
let chainID = ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.chainID : tools.getUUID();
|
|
218
|
-
let chainLevel = ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.chainLevel + 1 : 0;
|
|
219
|
-
let source = {
|
|
220
|
-
instanceID: ServiceInstance.instanceID,
|
|
221
|
-
route: ServiceInstance.serviceDomainName
|
|
222
|
-
};
|
|
223
|
-
let destination = {
|
|
224
|
-
instanceID: undefined,
|
|
225
|
-
route: serviceAddress.serviceDomainName
|
|
226
|
-
};
|
|
227
|
-
/** @type ServiceCall */
|
|
228
|
-
let serviceCall = {
|
|
229
|
-
authToken: serviceExecContext.authToken,
|
|
230
|
-
chainID: chainID,
|
|
231
|
-
chainLevel: chainLevel,
|
|
232
|
-
createdOn: Date.now(),
|
|
233
|
-
destination: destination,
|
|
234
|
-
executionTime: 0,
|
|
235
|
-
exception: undefined,
|
|
236
|
-
finishedOn: undefined,
|
|
237
|
-
isCompleted: false,
|
|
238
|
-
isSuccessful: undefined,
|
|
239
|
-
messageID: tools.getUUID(),
|
|
240
|
-
payload: undefined,
|
|
241
|
-
predecessor: ( serviceExecContext.previousServiceCall ) ? serviceExecContext.previousServiceCall.messageID : undefined,
|
|
242
|
-
serviceAddress: serviceAddress,
|
|
243
|
-
serviceParams: serviceParams,
|
|
244
|
-
source: source,
|
|
245
|
-
successors: undefined
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
resolve( serviceCall );
|
|
249
|
-
} );
|
|
365
|
+
onConnectionLost( identifier ) {
|
|
366
|
+
super.onConnectionLost( identifier );
|
|
250
367
|
}
|
|
251
368
|
|
|
252
|
-
|
|
253
|
-
* Used to complete the provided {@link ServiceCall} object by setting all required properties to their correct values.
|
|
254
|
-
*
|
|
255
|
-
* @method
|
|
256
|
-
* @param {ServiceCall} serviceCall
|
|
257
|
-
* @returns {Promise<ServiceCall>}
|
|
258
|
-
* @private
|
|
259
|
-
*/
|
|
260
|
-
#completeServiceCall( serviceCall ) {
|
|
261
|
-
return new Promise( ( resolve ) => {
|
|
262
|
-
serviceCall.finishedOn = Date.now();
|
|
263
|
-
serviceCall.executionTime = serviceCall.finishedOn - serviceCall.createdOn;
|
|
264
|
-
serviceCall.isCompleted = true;
|
|
265
|
-
|
|
266
|
-
resolve( serviceCall );
|
|
267
|
-
} );
|
|
268
|
-
}
|
|
369
|
+
/* Private interface */
|
|
269
370
|
|
|
270
371
|
/**
|
|
271
372
|
* Used to add a new task handler to the list of current tasks.
|
|
272
373
|
*
|
|
273
374
|
* @method
|
|
274
|
-
* @param {string}
|
|
275
|
-
* @param {
|
|
375
|
+
* @param {string} messageID
|
|
376
|
+
* @param {ServiceCallProcessor} processor
|
|
276
377
|
* @private
|
|
277
378
|
*/
|
|
278
|
-
#
|
|
279
|
-
this.#
|
|
379
|
+
#addProcessor( messageID, processor ) {
|
|
380
|
+
this.#serviceCallProcessors[ messageID ] = processor;
|
|
280
381
|
}
|
|
281
382
|
|
|
282
383
|
/**
|
|
283
384
|
* Used to fetch a task handler from the list of current tasks.
|
|
284
385
|
*
|
|
285
386
|
* @method
|
|
286
|
-
* @param {string}
|
|
287
|
-
* @returns {
|
|
387
|
+
* @param {string} messageID
|
|
388
|
+
* @returns {ServiceCallProcessor}
|
|
288
389
|
* @private
|
|
289
390
|
*/
|
|
290
|
-
#
|
|
291
|
-
return this.#
|
|
391
|
+
#getProcessor( messageID ) {
|
|
392
|
+
return this.#serviceCallProcessors[ messageID ];
|
|
292
393
|
}
|
|
293
394
|
|
|
294
395
|
/**
|
|
295
396
|
* Used to remove a task handler from the list of current tasks.
|
|
296
397
|
*
|
|
297
398
|
* @method
|
|
298
|
-
* @param {string}
|
|
399
|
+
* @param {string} messageID
|
|
299
400
|
* @private
|
|
300
401
|
*/
|
|
301
|
-
#
|
|
302
|
-
if ( this.#
|
|
303
|
-
delete this.#
|
|
402
|
+
#removeProcessor( messageID ) {
|
|
403
|
+
if ( this.#serviceCallProcessors[ messageID ] ) {
|
|
404
|
+
delete this.#serviceCallProcessors[ messageID ];
|
|
304
405
|
}
|
|
305
406
|
}
|
|
306
407
|
|
|
@@ -91,16 +91,19 @@ class ServiceExecutor extends MessageObserver {
|
|
|
91
91
|
*
|
|
92
92
|
* @method
|
|
93
93
|
* @param {string} identifier The identifier of the observed connection.
|
|
94
|
-
* @param {
|
|
94
|
+
* @param {ServiceCall} serviceCall The service call message for processing.
|
|
95
|
+
* @returns {ServiceCall} The service call message that was received.
|
|
95
96
|
* @override
|
|
96
97
|
* @public
|
|
97
98
|
*/
|
|
98
|
-
onMessage( identifier,
|
|
99
|
-
this.#processServiceCall(
|
|
99
|
+
onMessage( identifier, serviceCall ) {
|
|
100
|
+
this.#processServiceCall( serviceCall ).then( ( serviceCall ) => {
|
|
100
101
|
return messageDispatcher.instance.sendResponse( serviceCall );
|
|
101
102
|
} ).catch( ( error ) => {
|
|
102
|
-
logger.log( `Failed to send service call response after processing! Service call ID was: '${
|
|
103
|
+
logger.log( `Failed to send service call response after processing! Service call message ID was: '${ serviceCall.messageID }'`, logger.logSeverity.ERROR, error );
|
|
103
104
|
} );
|
|
105
|
+
|
|
106
|
+
return serviceCall;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
/**
|
|
@@ -127,6 +130,18 @@ class ServiceExecutor extends MessageObserver {
|
|
|
127
130
|
super.onConnectionRecovered( identifier );
|
|
128
131
|
}
|
|
129
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Needs to be invoked by the connection handler when the connection is irrevocably lost.
|
|
135
|
+
*
|
|
136
|
+
* @method
|
|
137
|
+
* @param {string} identifier The identifier of the observed connection.
|
|
138
|
+
* @override
|
|
139
|
+
* @public
|
|
140
|
+
*/
|
|
141
|
+
onConnectionLost( identifier ) {
|
|
142
|
+
super.onConnectionLost( identifier );
|
|
143
|
+
}
|
|
144
|
+
|
|
130
145
|
/**
|
|
131
146
|
* Used to set up the method for service access verification.
|
|
132
147
|
*
|
|
@@ -37,6 +37,7 @@ class ServiceInstance {
|
|
|
37
37
|
#serviceConfig;
|
|
38
38
|
#serviceHealthCheck;
|
|
39
39
|
#reportHealthyJob;
|
|
40
|
+
#healthReportUnderway = false;
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
43
|
* @constructor
|
|
@@ -225,10 +226,14 @@ class ServiceInstance {
|
|
|
225
226
|
* @public
|
|
226
227
|
*/
|
|
227
228
|
reportHealthy() {
|
|
228
|
-
if ( cache.instance.isOperational ) {
|
|
229
|
+
if ( cache.instance.isOperational && !this.#healthReportUnderway ) {
|
|
230
|
+
this.#healthReportUnderway = true;
|
|
229
231
|
let timestamp = new Date();
|
|
230
|
-
cache.instance.setValue( this.#serviceHealthCheck, timestamp.toISOString(), config.getSetting( config.setting.SERVICE_HEALTH_CHECK_TIMEOUT ) ).
|
|
231
|
-
|
|
232
|
+
cache.instance.setValue( this.#serviceHealthCheck, timestamp.toISOString(), config.getSetting( config.setting.SERVICE_HEALTH_CHECK_TIMEOUT ) ).then( () => {
|
|
233
|
+
this.#healthReportUnderway = false;
|
|
234
|
+
} ).catch( ( error ) => {
|
|
235
|
+
this.#healthReportUnderway = false;
|
|
236
|
+
logger.log( `Failed to report for health check from instance '${ ServiceInstance.instanceID }'!`, logger.logSeverity.WARNING, error );
|
|
232
237
|
} );
|
|
233
238
|
}
|
|
234
239
|
}
|