@ti-engine/core 1.0.1 → 1.0.2
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 +3 -1
- package/package.json +4 -3
- package/start-instance.js +107 -0
- package/utils/config.js +11 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ The **@ti-engine/core** is an open source, free to use - both for personal and c
|
|
|
6
6
|
|
|
7
7
|
Being a messenger system, the **@ti-engine/core** relies on a message broker for the actual exchange of messages between microservice instances. The default implementation of the framework uses [Redis](https://redis.io/) cache, however, you could create your own implementation using something like [Rabbit MQ](https://www.rabbitmq.com/). See the [advanced topics](#advanced-topics) section of this documentation for guides on how to do this.
|
|
8
8
|
|
|
9
|
-
Please be aware, that this framework is under active development and will expand in the near future. Make sure to keep an eye on the changes in case you want to use it in the meantime.
|
|
9
|
+
Please be aware, that this framework is under active development and will expand in the near future. Also, this documentation is still in the process of being created and refined. Make sure to keep an eye on the changes in case you want to use it in the meantime.
|
|
10
10
|
|
|
11
11
|
## prerequisites & installation
|
|
12
12
|
In order to run the basic ti-engine framework you will need a couple of things:
|
|
@@ -16,6 +16,8 @@ In order to run the basic ti-engine framework you will need a couple of things:
|
|
|
16
16
|
To get the framework itself, use the command `npm install @ti-engine/core`. And to include it directly in your package.json dependencies execute `npm install @ti-engine/core --save-prod`.
|
|
17
17
|
|
|
18
18
|
## getting started
|
|
19
|
+
To start using the ti-engine, you will have to make sure that the framework is properly configured and able to run. More details and instructions will be provided in the next version of this documentation. For now please take a look at the included file `start-instance.js`. It should give you an idea of how the engine operates and what to do in order to create and run your own microservice instance.
|
|
20
|
+
|
|
19
21
|
Under development...
|
|
20
22
|
|
|
21
23
|
## architecture
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ti-engine/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "The ti-engine is an open source, free to use - both for personal and commercial projects - framework for the creation of microservice-based solutions using node.js.",
|
|
5
5
|
"author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
|
|
6
6
|
"license": "ISC",
|
|
@@ -40,13 +40,14 @@
|
|
|
40
40
|
"#tools": "./utils/tools.js"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"dotenv": "^10.0.0",
|
|
43
44
|
"fs-extra": "^10.0.0",
|
|
44
45
|
"lodash": "^4.17.21",
|
|
45
46
|
"node-schedule": "^2.0.0",
|
|
46
|
-
"ioredis": "^4.
|
|
47
|
+
"ioredis": "^4.28.1"
|
|
47
48
|
},
|
|
48
49
|
"optionalDependencies": {
|
|
49
|
-
"@google-cloud/error-reporting": "^2.0.
|
|
50
|
+
"@google-cloud/error-reporting": "^2.0.4"
|
|
50
51
|
},
|
|
51
52
|
"engines": {
|
|
52
53
|
"node": ">=14.17.0"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-FileCopyrightText: © 2021 Boris Kostadinov <kostadinov.boris@gmail.com>
|
|
3
|
+
* SPDX-License-Identifier: ICU
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
// load any ENV variables defined in a .env file:
|
|
9
|
+
require( "dotenv" ).config();
|
|
10
|
+
|
|
11
|
+
const _ = require( "lodash" );
|
|
12
|
+
const fs = require( "fs-extra" );
|
|
13
|
+
const tools = require( "#tools" );
|
|
14
|
+
const logger = require( "#logger" );
|
|
15
|
+
|
|
16
|
+
// configure the current instance variables before requiring any platform modules and store the necessary ones in memory cache:
|
|
17
|
+
process.env.TI_INSTANCE_ID = "ti-" + tools.getUUID();
|
|
18
|
+
process.env.TI_INSTANCE_CLASS = process.env.TI_INSTANCE_CLASS || "";
|
|
19
|
+
process.env.TI_INSTANCE_NAME = process.env.TI_INSTANCE_NAME || _.last( _.split( process.env.TI_INSTANCE_CLASS, "/" ) );
|
|
20
|
+
|
|
21
|
+
// configure the process error handlers:
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Will be used to gracefully shut down the instance.
|
|
25
|
+
* NOTE: Will be overridden below after the instance creation.
|
|
26
|
+
*
|
|
27
|
+
* @method
|
|
28
|
+
* @param {number} exitCode
|
|
29
|
+
* @abstract
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
let shutDownInstance = ( exitCode ) => {
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// this event will handle the process termination (Ctrl + C):
|
|
36
|
+
process.on( "SIGINT", () => {
|
|
37
|
+
logger.log( `SIGINT event detected in main instance process.`, logger.logSeverity.NOTICE );
|
|
38
|
+
shutDownInstance( 0 );
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
// this event will handle the process termination (CMD close):
|
|
42
|
+
process.on( "SIGHUP", () => {
|
|
43
|
+
logger.log( `SIGHUP event detected in main instance process.`, logger.logSeverity.NOTICE );
|
|
44
|
+
shutDownInstance( 0 );
|
|
45
|
+
} );
|
|
46
|
+
|
|
47
|
+
// this event will handle the process termination:
|
|
48
|
+
process.on( "SIGTERM", () => {
|
|
49
|
+
logger.log( `SIGTERM event detected in main instance process.`, logger.logSeverity.NOTICE );
|
|
50
|
+
shutDownInstance( 0 );
|
|
51
|
+
} );
|
|
52
|
+
|
|
53
|
+
process.on( "unhandledRejection", ( reason, promise ) => {
|
|
54
|
+
logger.log( `Unhandled promise rejection identified! Make sure this isn't a software bug.`, logger.logSeverity.WARNING, {
|
|
55
|
+
reason: reason,
|
|
56
|
+
promise: tools.stringifyJSON( promise )
|
|
57
|
+
} );
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
process.on( "multipleResolves", ( type, promise, reason ) => {
|
|
61
|
+
logger.log( `Multiple promise resolves detected! Make sure this isn't a software bug.`, logger.logSeverity.WARNING, {
|
|
62
|
+
reason: reason,
|
|
63
|
+
promise: tools.stringifyJSON( promise )
|
|
64
|
+
} );
|
|
65
|
+
} );
|
|
66
|
+
|
|
67
|
+
process.on( "uncaughtException", ( error ) => {
|
|
68
|
+
logger.log( `Some nasty and uncaught error just occurred in the application!`, logger.logSeverity.ALERT, error );
|
|
69
|
+
setImmediate( () => process.exit( 1 ) );
|
|
70
|
+
} );
|
|
71
|
+
|
|
72
|
+
// start the instance:
|
|
73
|
+
try {
|
|
74
|
+
logger.log( `Starting new instance of type '${ process.env.TI_INSTANCE_NAME }' with instance ID '${ process.env.TI_INSTANCE_ID }'.`, logger.logSeverity.NOTICE );
|
|
75
|
+
|
|
76
|
+
/** @type ServiceInstance */
|
|
77
|
+
const serviceConstructor = require( process.env.TI_INSTANCE_CLASS );
|
|
78
|
+
const serviceConfigPath = process.env.TI_INSTANCE_CONFIG;
|
|
79
|
+
let serviceConfig = {};
|
|
80
|
+
if ( fs.existsSync( serviceConfigPath ) ) {
|
|
81
|
+
serviceConfig = require( process.env.TI_INSTANCE_CONFIG );
|
|
82
|
+
}
|
|
83
|
+
const mainInstance = new serviceConstructor( process.env.TI_INSTANCE_NAME, serviceConfig );
|
|
84
|
+
|
|
85
|
+
/** @override */
|
|
86
|
+
shutDownInstance = ( code ) => {
|
|
87
|
+
mainInstance.stop().then( () => {
|
|
88
|
+
setImmediate( () => process.exit( code ) );
|
|
89
|
+
} ).catch( ( error ) => {
|
|
90
|
+
logger.log( `Error occurred during shut down of instance '${ process.env.TI_INSTANCE_ID }'! Exit code changed from '${ code }' to '1'.`, logger.logSeverity.ERROR, error );
|
|
91
|
+
setImmediate( () => process.exit( 1 ) );
|
|
92
|
+
} );
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if ( mainInstance.isServiceInstance ) {
|
|
96
|
+
mainInstance.start().catch( ( error ) => {
|
|
97
|
+
logger.log( `Error detected during instance '${ process.env.TI_INSTANCE_ID }' startup!`, logger.logSeverity.ALERT, error );
|
|
98
|
+
setImmediate( () => process.exit( 1 ) );
|
|
99
|
+
} );
|
|
100
|
+
} else {
|
|
101
|
+
logger.log( `Attempting to start a module that does not implement the ServiceInstance abstract class!`, logger.logSeverity.ERROR );
|
|
102
|
+
setImmediate( () => process.exit( 1 ) );
|
|
103
|
+
}
|
|
104
|
+
} catch ( error ) {
|
|
105
|
+
logger.log( `Error detected in the instance startup script!`, logger.logSeverity.ALERT, error );
|
|
106
|
+
setImmediate( () => process.exit( 1 ) );
|
|
107
|
+
}
|
package/utils/config.js
CHANGED
|
@@ -23,6 +23,10 @@ const tools = require( "#tools" );
|
|
|
23
23
|
* @property {EnvironmentVariable} env.TI_LOG_CONSOLE_ENABLED
|
|
24
24
|
* @property {EnvironmentVariable} env.TI_LOG_MIN_LEVEL
|
|
25
25
|
* @property {EnvironmentVariable} env.TI_LOG_USED_JSON
|
|
26
|
+
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_AUTH_KEY
|
|
27
|
+
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_DB
|
|
28
|
+
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_HOST
|
|
29
|
+
* @property {EnvironmentVariable} env.TI_MEMORY_CACHE_PORT
|
|
26
30
|
* @property {EnvironmentVariable} env.TI_OPERATION_MODE
|
|
27
31
|
*/
|
|
28
32
|
|
|
@@ -116,10 +120,16 @@ const settings = require( "#settings" );
|
|
|
116
120
|
|
|
117
121
|
// override remaining settings with ENV variables (if provided):
|
|
118
122
|
if ( settings.auditing ) {
|
|
119
|
-
settings.auditing.logMinLevel = ( process.env.TI_LOG_MIN_LEVEL !== undefined ) ? process.env.
|
|
123
|
+
settings.auditing.logMinLevel = ( process.env.TI_LOG_MIN_LEVEL !== undefined ) ? process.env.TI_LOG_MIN_LEVEL : settings.auditing.logMinLevel;
|
|
120
124
|
settings.auditing.logConsoleEnabled = ( process.env.TI_LOG_CONSOLE_ENABLED !== undefined ) ? tools.toBool( process.env.TI_LOG_CONSOLE_ENABLED ) : settings.auditing.logConsoleEnabled;
|
|
121
125
|
settings.auditing.logUsesJSON = ( process.env.TI_LOG_USED_JSON !== undefined ) ? tools.toBool( process.env.TI_LOG_USED_JSON ) : settings.auditing.logUsesJSON;
|
|
122
126
|
}
|
|
127
|
+
if ( settings.memoryCache ) {
|
|
128
|
+
settings.memoryCache.authKey = ( process.env.TI_MEMORY_CACHE_AUTH_KEY !== undefined ) ? process.env.TI_MEMORY_CACHE_AUTH_KEY : settings.memoryCache.authKey;
|
|
129
|
+
settings.memoryCache.redisDB = ( process.env.TI_MEMORY_CACHE_DB !== undefined ) ? process.env.TI_MEMORY_CACHE_DB : settings.memoryCache.redisDB;
|
|
130
|
+
settings.memoryCache.redisHost = ( process.env.TI_MEMORY_CACHE_HOST !== undefined ) ? process.env.TI_MEMORY_CACHE_HOST : settings.memoryCache.redisHost;
|
|
131
|
+
settings.memoryCache.redisPort = ( process.env.TI_MEMORY_CACHE_PORT !== undefined ) ? process.env.TI_MEMORY_CACHE_PORT : settings.memoryCache.redisPort;
|
|
132
|
+
}
|
|
123
133
|
|
|
124
134
|
// make sure GCloud is enabled before trying to setup it:
|
|
125
135
|
if ( process.env.TI_GCLOUD_ENABLED === true && settings.gcloudIntegration ) {
|