-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
148 lines (135 loc) · 3.91 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
'use strict'
const pm2 = require('pm2')
const path = require('path')
const pkgmgr = require('@elife/pkg-mgr')
const u = require('@elife/utils')
if(!process.env.IN_DOCKER){
const dotenv = require('dotenv').config({ path : path.join(u.dataLoc(),'cfg.env')})
}
/* understand/
* This is the main entry point where we start.
*
* outcome/
* Load any configuration information and start the core processes.
*/
function main() {
let conf = loadConfig()
startCoreProcesses(conf)
}
/* outcome/
* Load the configuration (from environment variables) or defaults
*/
function loadConfig() {
let cfg = {};
if(process.env.SVC_FOLDER) {
cfg.SVC_FOLDER = process.env.SVC_FOLDER;
} else {
cfg.SVC_FOLDER = "./services";
}
return cfg;
}
/* outcome/
* The main responsibility of the avatar is to stay running and stable
* (after all it has to *live forever*). For this to work, it delegates
* all other work to different processes (a.l.a Erlang's supervisor
* trees).
*
* These core processes include:
* 1. The Scuttlebot Immortal Feed and Replication
* 2. A Database for storing working data
* 3. A Skill Manager for installing, running, and managing skills
* - Infrastructure Skills (as hub/as host/...)
* - Worker skills (twitter svc, vanity address, ...)
* 4. A Communication Manager for installing, running, and managing
* communication channels
- Telegram channel
- Messenger channel
- Alexa channel
- Web channel
- ...
* 5. An AI for understanding and managing user interaction and
* strategies for earning
* - Cakechat (python with microservices relay...)
* - ...
* 6. The stellar blockchain interface for payments, receipts, and smart
* contracts.
*
* The avatar downloads, installs, and starts the core processes.
*
* TODO: Monitoring and regulating component CPU/Memory/Disk usage
*/
function startCoreProcesses(cfg) {
const core_procs = [
{ pkg: "everlifeai/elife-ai" },
{ pkg: "everlifeai/elife-sbot" },
{ pkg: "everlifeai/elife-level-db" },
{ pkg: "everlifeai/elife-skill-mgr" },
{ pkg: "everlifeai/elife-communication-mgr" },
{ pkg: "everlifeai/elife-stellar" },
];
u.showMsg(`Installing core packages...`)
load_pkgs_1(0, (err) => {
if(err) {
u.showErr(err)
process.exit(1)
} else {
u.showMsg(`Starting core functionality...`)
start_processes_1((err) => {
if(err) {
u.showErr(err)
process.exit(2)
}
})
}
})
function load_pkgs_1(ndx, cb) {
if(core_procs.length <= ndx) return cb()
let pkg = core_procs[ndx].pkg
u.showMsg(`Loading ${pkg}...`)
pkgmgr.load(pkg, cfg.SVC_FOLDER, (err, loc) => {
if(err) cb(err)
else {
core_procs[ndx].loc = loc
load_pkgs_1(ndx+1, cb)
}
})
}
function start_processes_1(cb) {
pm2.connect(true, (err) => {
if(err) cb(err)
else start_procs_1(0, cb)
})
}
function start_procs_1(ndx, cb) {
if(core_procs.length <= ndx) return cb()
let loc = core_procs[ndx].loc
u.showMsg(`Starting ${loc}...`)
startProcess(cfg, loc, (err) => {
if(err) cb(err)
else start_procs_1(ndx+1, cb)
})
}
}
function startProcess(cfg, cwd, cb) {
let name = path.basename(cwd)
let lg = path.join(__dirname, 'logs', `${name}.log`)
let opts = {
name: name,
script: "index.js",
cwd: cwd,
log: lg,
}
pm2.start(opts, cb)
}
process.on('SIGINT', () => {
stopAllChildProcesses()
})
process.on('exit', () => {
stopAllChildProcesses()
})
function stopAllChildProcesses() {
pm2.connect(true, (err) => {
pm2.stop('all')
})
}
main()