@ruvector/edge-net 0.4.1 → 0.4.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/deploy/.env.example +97 -0
- package/deploy/DEPLOY.md +481 -0
- package/deploy/Dockerfile +99 -0
- package/deploy/docker-compose.yml +162 -0
- package/deploy/genesis-prod.js +1536 -0
- package/deploy/health-check.js +187 -0
- package/deploy/prometheus.yml +38 -0
- package/firebase-signaling.js +242 -53
- package/package.json +19 -3
- package/real-workers.js +9 -4
- package/scheduler.js +8 -4
- package/secure-access.js +595 -0
- package/tests/distributed-workers-test.js +1609 -0
- package/tests/p2p-migration-test.js +1102 -0
- package/tests/webrtc-peer-test.js +686 -0
- package/webrtc.js +727 -50
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @ruvector/edge-net Genesis Node Health Check
|
|
4
|
+
*
|
|
5
|
+
* Standalone health check script for use with container orchestrators,
|
|
6
|
+
* load balancers, and monitoring systems.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* node deploy/health-check.js # Check localhost:8788
|
|
10
|
+
* node deploy/health-check.js --host 10.0.0.1 # Check specific host
|
|
11
|
+
* node deploy/health-check.js --port 9000 # Check specific port
|
|
12
|
+
* node deploy/health-check.js --endpoint ready # Check readiness
|
|
13
|
+
* node deploy/health-check.js --json # JSON output
|
|
14
|
+
*
|
|
15
|
+
* Exit codes:
|
|
16
|
+
* 0 - Healthy
|
|
17
|
+
* 1 - Unhealthy or error
|
|
18
|
+
*
|
|
19
|
+
* @module @ruvector/edge-net/deploy/health-check
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import http from 'http';
|
|
23
|
+
|
|
24
|
+
// Parse arguments
|
|
25
|
+
const args = process.argv.slice(2);
|
|
26
|
+
const config = {
|
|
27
|
+
host: 'localhost',
|
|
28
|
+
port: 8788,
|
|
29
|
+
endpoint: 'health',
|
|
30
|
+
timeout: 5000,
|
|
31
|
+
json: false,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < args.length; i++) {
|
|
35
|
+
switch (args[i]) {
|
|
36
|
+
case '--host':
|
|
37
|
+
case '-h':
|
|
38
|
+
config.host = args[++i];
|
|
39
|
+
break;
|
|
40
|
+
case '--port':
|
|
41
|
+
case '-p':
|
|
42
|
+
config.port = parseInt(args[++i]);
|
|
43
|
+
break;
|
|
44
|
+
case '--endpoint':
|
|
45
|
+
case '-e':
|
|
46
|
+
config.endpoint = args[++i];
|
|
47
|
+
break;
|
|
48
|
+
case '--timeout':
|
|
49
|
+
case '-t':
|
|
50
|
+
config.timeout = parseInt(args[++i]);
|
|
51
|
+
break;
|
|
52
|
+
case '--json':
|
|
53
|
+
case '-j':
|
|
54
|
+
config.json = true;
|
|
55
|
+
break;
|
|
56
|
+
case '--help':
|
|
57
|
+
console.log(`
|
|
58
|
+
Genesis Node Health Check
|
|
59
|
+
|
|
60
|
+
Usage: node health-check.js [options]
|
|
61
|
+
|
|
62
|
+
Options:
|
|
63
|
+
--host, -h <host> Host to check (default: localhost)
|
|
64
|
+
--port, -p <port> Port to check (default: 8788)
|
|
65
|
+
--endpoint, -e <path> Endpoint to check: health, ready, status, metrics (default: health)
|
|
66
|
+
--timeout, -t <ms> Request timeout in milliseconds (default: 5000)
|
|
67
|
+
--json, -j Output JSON format
|
|
68
|
+
--help Show this help
|
|
69
|
+
|
|
70
|
+
Examples:
|
|
71
|
+
node health-check.js
|
|
72
|
+
node health-check.js --host genesis.example.com --port 8788
|
|
73
|
+
node health-check.js --endpoint ready
|
|
74
|
+
node health-check.js --json
|
|
75
|
+
|
|
76
|
+
Exit Codes:
|
|
77
|
+
0 - Healthy/Ready
|
|
78
|
+
1 - Unhealthy/Not Ready/Error
|
|
79
|
+
`);
|
|
80
|
+
process.exit(0);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function checkHealth() {
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
const startTime = Date.now();
|
|
87
|
+
|
|
88
|
+
const req = http.get({
|
|
89
|
+
hostname: config.host,
|
|
90
|
+
port: config.port,
|
|
91
|
+
path: `/${config.endpoint}`,
|
|
92
|
+
timeout: config.timeout,
|
|
93
|
+
}, (res) => {
|
|
94
|
+
let data = '';
|
|
95
|
+
|
|
96
|
+
res.on('data', chunk => data += chunk);
|
|
97
|
+
res.on('end', () => {
|
|
98
|
+
const latency = Date.now() - startTime;
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const parsed = JSON.parse(data);
|
|
102
|
+
resolve({
|
|
103
|
+
healthy: res.statusCode === 200,
|
|
104
|
+
statusCode: res.statusCode,
|
|
105
|
+
latency,
|
|
106
|
+
data: parsed,
|
|
107
|
+
});
|
|
108
|
+
} catch {
|
|
109
|
+
resolve({
|
|
110
|
+
healthy: res.statusCode === 200,
|
|
111
|
+
statusCode: res.statusCode,
|
|
112
|
+
latency,
|
|
113
|
+
data: data,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
req.on('error', (err) => {
|
|
120
|
+
reject({
|
|
121
|
+
healthy: false,
|
|
122
|
+
error: err.message,
|
|
123
|
+
latency: Date.now() - startTime,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
req.on('timeout', () => {
|
|
128
|
+
req.destroy();
|
|
129
|
+
reject({
|
|
130
|
+
healthy: false,
|
|
131
|
+
error: 'Request timeout',
|
|
132
|
+
latency: config.timeout,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function main() {
|
|
139
|
+
try {
|
|
140
|
+
const result = await checkHealth();
|
|
141
|
+
|
|
142
|
+
if (config.json) {
|
|
143
|
+
console.log(JSON.stringify({
|
|
144
|
+
...result,
|
|
145
|
+
host: config.host,
|
|
146
|
+
port: config.port,
|
|
147
|
+
endpoint: config.endpoint,
|
|
148
|
+
timestamp: new Date().toISOString(),
|
|
149
|
+
}, null, 2));
|
|
150
|
+
} else {
|
|
151
|
+
if (result.healthy) {
|
|
152
|
+
console.log(`OK - ${config.host}:${config.port}/${config.endpoint} (${result.latency}ms)`);
|
|
153
|
+
|
|
154
|
+
if (result.data?.ready !== undefined) {
|
|
155
|
+
console.log(` Ready: ${result.data.ready}`);
|
|
156
|
+
}
|
|
157
|
+
if (result.data?.status) {
|
|
158
|
+
console.log(` Status: ${result.data.status}`);
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
console.log(`FAIL - ${config.host}:${config.port}/${config.endpoint}`);
|
|
162
|
+
console.log(` Status Code: ${result.statusCode}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
process.exit(result.healthy ? 0 : 1);
|
|
167
|
+
|
|
168
|
+
} catch (error) {
|
|
169
|
+
if (config.json) {
|
|
170
|
+
console.log(JSON.stringify({
|
|
171
|
+
healthy: false,
|
|
172
|
+
host: config.host,
|
|
173
|
+
port: config.port,
|
|
174
|
+
endpoint: config.endpoint,
|
|
175
|
+
error: error.error || error.message,
|
|
176
|
+
timestamp: new Date().toISOString(),
|
|
177
|
+
}, null, 2));
|
|
178
|
+
} else {
|
|
179
|
+
console.log(`ERROR - ${config.host}:${config.port}/${config.endpoint}`);
|
|
180
|
+
console.log(` Error: ${error.error || error.message}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
main();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Prometheus configuration for Edge-Net Genesis Node monitoring
|
|
2
|
+
#
|
|
3
|
+
# Scrapes metrics from genesis nodes at /metrics endpoint
|
|
4
|
+
|
|
5
|
+
global:
|
|
6
|
+
scrape_interval: 15s
|
|
7
|
+
evaluation_interval: 15s
|
|
8
|
+
external_labels:
|
|
9
|
+
cluster: 'edge-net-local'
|
|
10
|
+
|
|
11
|
+
alerting:
|
|
12
|
+
alertmanagers: []
|
|
13
|
+
|
|
14
|
+
rule_files: []
|
|
15
|
+
|
|
16
|
+
scrape_configs:
|
|
17
|
+
# Primary Genesis Node
|
|
18
|
+
- job_name: 'genesis'
|
|
19
|
+
static_configs:
|
|
20
|
+
- targets: ['genesis:8788']
|
|
21
|
+
labels:
|
|
22
|
+
instance: 'genesis-primary'
|
|
23
|
+
metrics_path: /metrics
|
|
24
|
+
scrape_interval: 10s
|
|
25
|
+
|
|
26
|
+
# Secondary Genesis Node (if cluster profile enabled)
|
|
27
|
+
- job_name: 'genesis-cluster'
|
|
28
|
+
static_configs:
|
|
29
|
+
- targets: ['genesis-2:8788']
|
|
30
|
+
labels:
|
|
31
|
+
instance: 'genesis-secondary'
|
|
32
|
+
metrics_path: /metrics
|
|
33
|
+
scrape_interval: 10s
|
|
34
|
+
|
|
35
|
+
# Prometheus self-monitoring
|
|
36
|
+
- job_name: 'prometheus'
|
|
37
|
+
static_configs:
|
|
38
|
+
- targets: ['localhost:9090']
|