jsir 3.0.0 → 3.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/cmd/oaa.js +26 -9
- package/deps/room.js +40 -23
- package/deps/util.js +33 -15
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -351,6 +351,8 @@ function initRl(callback, promptStr, hidden, reject) {
|
|
|
351
351
|
_rl.clearLine(0)
|
|
352
352
|
if (callback === wrapperInput) {
|
|
353
353
|
nextLine();
|
|
354
|
+
} else {
|
|
355
|
+
closeRl()
|
|
354
356
|
}
|
|
355
357
|
}
|
|
356
358
|
});
|
|
@@ -1128,23 +1130,24 @@ async function showRooms() {
|
|
|
1128
1130
|
for (let i = 0; i < setting.rooms.length; i++) {
|
|
1129
1131
|
let room = setting.rooms[i]
|
|
1130
1132
|
let isLocal = setting.selfRoom.selfNode === room.selfNode;
|
|
1133
|
+
let roomName = room.active ? infoStr(room.name):room.name;
|
|
1134
|
+
let delayStr = vl(room.delay) ? (room.delay + "ms"):"";
|
|
1131
1135
|
results.push({
|
|
1132
|
-
name: (isLocal ? "*" : " ") +
|
|
1136
|
+
name: (isLocal ? infoStr("*") : " ") + roomName,
|
|
1133
1137
|
node: room.selfNode,
|
|
1134
|
-
|
|
1138
|
+
delay: delayStr
|
|
1135
1139
|
})
|
|
1136
1140
|
for (let key of Object.keys(room.jsirs)) {
|
|
1137
1141
|
let jsir = room.jsirs[key]
|
|
1138
|
-
let pidStr = (process.pid === jsir.pid ? "*" : " ") + jsir.pid;
|
|
1142
|
+
let pidStr = (process.pid === jsir.pid ? infoStr("*") : " ") + (jsir.newError ? errorStr(jsir.pid):(jsir.active ? infoStr(jsir.pid):jsir.pid));
|
|
1139
1143
|
results.push({
|
|
1140
|
-
name: (isLocal ? "*" : " ") +
|
|
1144
|
+
name: (isLocal ? infoStr("*") : " ") + roomName,
|
|
1141
1145
|
node: room.selfNode,
|
|
1142
|
-
|
|
1143
|
-
pid:
|
|
1146
|
+
delay: delayStr,
|
|
1147
|
+
pid: pidStr,
|
|
1144
1148
|
up: formatSec(jsir.upTime) || '',
|
|
1145
1149
|
version: jsir.version || '',
|
|
1146
1150
|
space: jsir.space,
|
|
1147
|
-
running: jsir.active,
|
|
1148
1151
|
port: jsir.port,
|
|
1149
1152
|
back: jsir.back,
|
|
1150
1153
|
busy: jsir.busy,
|
|
@@ -1320,12 +1323,22 @@ const keywordDef = {
|
|
|
1320
1323
|
console.msg("config service offline")
|
|
1321
1324
|
} else if (_cmdMap[args[0]]){
|
|
1322
1325
|
let uniqueName = _cmdMap[args[0]];
|
|
1323
|
-
|
|
1326
|
+
let configPath = `${getConfigDir()}/${md5(uniqueName + (global.$TEST ? '.test':''))}.json`;
|
|
1327
|
+
if (isRunningInBackground()) {
|
|
1328
|
+
console.log(String(await fp.readFile(configPath)).trim())
|
|
1329
|
+
} else {
|
|
1330
|
+
await eia(getEditor(), [`"${configPath}"`], true)
|
|
1331
|
+
}
|
|
1324
1332
|
} else {
|
|
1325
1333
|
console.warn('invalid args')
|
|
1326
1334
|
}
|
|
1327
1335
|
} else {
|
|
1328
|
-
|
|
1336
|
+
let configPath = `${getLibDataDir()}/config.json`;
|
|
1337
|
+
if (isRunningInBackground()) {
|
|
1338
|
+
console.log(String(await fp.readFile(configPath)).trim())
|
|
1339
|
+
} else {
|
|
1340
|
+
await eia(getEditor(), [`"${configPath}"`], true)
|
|
1341
|
+
}
|
|
1329
1342
|
}
|
|
1330
1343
|
},
|
|
1331
1344
|
short: 's'
|
|
@@ -1703,6 +1716,10 @@ const keywordDef = {
|
|
|
1703
1716
|
if (setting.selfRoom.selfNode === room.selfNode && String(process.pid) === pid) {
|
|
1704
1717
|
continue;
|
|
1705
1718
|
}
|
|
1719
|
+
if (setting.selfRoom.selfNode !== room.selfNode && args.includes(room.selfNode) && !args.includes(pid)
|
|
1720
|
+
&& room.jsirs[pid].port === setting.defaultPort) {
|
|
1721
|
+
continue;
|
|
1722
|
+
}
|
|
1706
1723
|
have = true;
|
|
1707
1724
|
tasks.push(async (input) => {
|
|
1708
1725
|
let jsir = room.jsirs[pid];
|
package/deps/room.js
CHANGED
|
@@ -3,7 +3,7 @@ const {fileJson, fileLock, vl, getKeyTips, getValTips,
|
|
|
3
3
|
getRoomsDir, e, isRunningInBackground,
|
|
4
4
|
batchAsync, trim, getOr, errorTag, warnStr, getConfig, getConfigDir,
|
|
5
5
|
fileExist, processLock, isPidAlive, cleanFileLocks,
|
|
6
|
-
roomConsole: console
|
|
6
|
+
roomConsole: console, reget
|
|
7
7
|
} = require('./util');
|
|
8
8
|
const {setRoute, createSign} = require('../deps/server')
|
|
9
9
|
const roomDataFile = "jsirRoom.json"
|
|
@@ -17,7 +17,6 @@ const http = require('http');
|
|
|
17
17
|
const tailscalePath = os.platform() === 'darwin' ?
|
|
18
18
|
'/Applications/Tailscale.app/Contents/MacOS/Tailscale':'tailscale';
|
|
19
19
|
const packageJson = require("../package.json");
|
|
20
|
-
const defTasks = getConfig("tasks");
|
|
21
20
|
|
|
22
21
|
async function localConfigs() {
|
|
23
22
|
let configDir = getConfigDir();
|
|
@@ -161,6 +160,7 @@ async function syncRooms() {
|
|
|
161
160
|
fns.push(async () => {
|
|
162
161
|
let respBody = ''
|
|
163
162
|
try {
|
|
163
|
+
let begin = Date.now();
|
|
164
164
|
try {
|
|
165
165
|
respBody = await reqNode(node, "get", "/");
|
|
166
166
|
} catch (e) {
|
|
@@ -178,6 +178,7 @@ async function syncRooms() {
|
|
|
178
178
|
Object.entries(currRoom.jsirs || {}).filter(([pid, jsir]) => jsir.port === setting.defaultPort)
|
|
179
179
|
);
|
|
180
180
|
}
|
|
181
|
+
currRoom.delay = Date.now() - begin;
|
|
181
182
|
syncRooms.push(currRoom)
|
|
182
183
|
console.$debug(`sync ${node} success`);
|
|
183
184
|
}
|
|
@@ -272,32 +273,45 @@ async function _syncSetting(room) {
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
async function processTasks() {
|
|
276
|
+
async function processTasks(defTasks) {
|
|
276
277
|
await fileJson(roomTasksFile, async tasks => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
278
|
+
for (let key of Object.keys(tasks)) {
|
|
279
|
+
let pids = tasks[key] || []
|
|
280
|
+
// 清理已经结束的进程
|
|
281
|
+
for (let i = 0; i < pids.length; i++) {
|
|
282
|
+
let pid = pids[i];
|
|
283
|
+
if (!isPidAlive(pid)) {
|
|
284
|
+
pids.splice(i, 1);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (pids.length === 0) {
|
|
288
|
+
delete tasks[key]
|
|
289
|
+
}
|
|
282
290
|
}
|
|
291
|
+
|
|
283
292
|
let unHandleKey = null;
|
|
284
293
|
for (let key of Object.keys(defTasks)) {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
+
let isMainPid = setting.defaultPort === setting.selfJsir.port;
|
|
295
|
+
let isMainTask = key.includes("*");
|
|
296
|
+
if (isMainPid !== isMainTask) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
let num = Number(reget(trim(key), /(\d+)$/) || 1);
|
|
301
|
+
let taskKey = trim(trim(key).replace(/\d+$/, ''));
|
|
302
|
+
let pids = tasks[taskKey] || [];
|
|
303
|
+
if (pids.length >= num || pids.includes(process.pid)) {
|
|
304
|
+
continue;
|
|
294
305
|
}
|
|
306
|
+
|
|
307
|
+
unHandleKey = key;
|
|
295
308
|
}
|
|
296
309
|
if (unHandleKey) {
|
|
297
310
|
console.$log(process.pid, `run task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
298
311
|
await setting.wrapperInput(defTasks[unHandleKey]);
|
|
299
312
|
if (!setting.newError) {
|
|
300
|
-
|
|
313
|
+
let taskKey = trim(trim(unHandleKey).replace(/\d+$/, ''));
|
|
314
|
+
tasks[taskKey] = [...(tasks[taskKey] || []), process.pid];
|
|
301
315
|
console.$log(process.pid, `handle task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
302
316
|
}
|
|
303
317
|
}
|
|
@@ -329,8 +343,9 @@ async function initRoom() {
|
|
|
329
343
|
await Promise.all(pros);
|
|
330
344
|
}, false).catch(console.$debug)
|
|
331
345
|
}
|
|
346
|
+
const defTasks = getConfig("tasks");
|
|
332
347
|
if (defTasks && Object.keys(defTasks).length > 0) {
|
|
333
|
-
processLock(roomTasksFile, processTasks, false).catch(console.$debug)
|
|
348
|
+
processLock(roomTasksFile, () => processTasks(defTasks), false).catch(console.$debug)
|
|
334
349
|
}
|
|
335
350
|
await syncSetting();
|
|
336
351
|
}
|
|
@@ -353,11 +368,11 @@ async function syncConfigs() {
|
|
|
353
368
|
let currText = String(await fp.readFile(path));
|
|
354
369
|
if (currText !== text) {
|
|
355
370
|
await fp.writeFile(path, text)
|
|
356
|
-
console.$debug(`
|
|
371
|
+
console.$debug(`update config ${key} success`);
|
|
357
372
|
}
|
|
358
373
|
} else {
|
|
359
374
|
await fp.writeFile(path, text)
|
|
360
|
-
console.$debug(`
|
|
375
|
+
console.$debug(`create config ${key} success`);
|
|
361
376
|
}
|
|
362
377
|
});
|
|
363
378
|
}
|
|
@@ -520,10 +535,12 @@ async function reqNode(node, method, url, port, body) {
|
|
|
520
535
|
});
|
|
521
536
|
|
|
522
537
|
// 设置超时逻辑
|
|
523
|
-
|
|
538
|
+
let timeoutMs = setting.reqNodeTimeouts[url];
|
|
539
|
+
if (timeoutMs) {
|
|
524
540
|
timeout = setTimeout(() => {
|
|
525
541
|
req.destroy(); // 中断请求
|
|
526
|
-
|
|
542
|
+
reject(new Error(`Timeout ${timeoutMs}ms`))
|
|
543
|
+
}, timeoutMs); // 10秒超时
|
|
527
544
|
}
|
|
528
545
|
|
|
529
546
|
// 错误处理
|
package/deps/util.js
CHANGED
|
@@ -844,7 +844,8 @@ function createLimitLogger(fileName, {
|
|
|
844
844
|
setting.newError = true;
|
|
845
845
|
}
|
|
846
846
|
if (time) {
|
|
847
|
-
|
|
847
|
+
let prefix = debugStr(`${timeStr('YYYY-MM-DD HH:mm:ss.SSS')} ${String(process.pid%1000).padStart(3, '0')}>`)
|
|
848
|
+
text = `${prefix} ${text}`
|
|
848
849
|
}
|
|
849
850
|
fp.appendFile(logPath, text + '\n')
|
|
850
851
|
let _minNum = (Date.now()/(1000 * 60 * 10)).toFixed(0)
|
|
@@ -1435,33 +1436,28 @@ function setTips(key, value, onRm) {
|
|
|
1435
1436
|
}
|
|
1436
1437
|
}
|
|
1437
1438
|
|
|
1438
|
-
function delTips(...keys) {
|
|
1439
|
+
async function delTips(...keys) {
|
|
1439
1440
|
keys = keys.map(trim).filter(i => i)
|
|
1440
|
-
let
|
|
1441
|
-
for (let key of Object.keys(setting.tips)) {
|
|
1441
|
+
for (let key of Object.keys(setting.tips).reverse()) {
|
|
1442
1442
|
if (keys.length === 0) {
|
|
1443
1443
|
if (['TEST', 'DEBUG'].includes(key)) {
|
|
1444
1444
|
continue
|
|
1445
1445
|
}
|
|
1446
1446
|
delete setting.tips[key]
|
|
1447
|
-
|
|
1447
|
+
await tipsOnRmCallback(key)
|
|
1448
1448
|
} else if (keys.indexOf(key) !== -1) {
|
|
1449
1449
|
delete setting.tips[key]
|
|
1450
|
-
|
|
1450
|
+
await tipsOnRmCallback(key)
|
|
1451
1451
|
}
|
|
1452
1452
|
}
|
|
1453
1453
|
if (keys.length === 0) {
|
|
1454
|
-
for (let key of Object.keys(setting.tipsOnRm)) {
|
|
1454
|
+
for (let key of Object.keys(setting.tipsOnRm).reverse()) {
|
|
1455
1455
|
if (['TEST', 'DEBUG'].includes(key)) {
|
|
1456
1456
|
continue
|
|
1457
1457
|
}
|
|
1458
|
-
|
|
1458
|
+
await tipsOnRmCallback(key)
|
|
1459
1459
|
}
|
|
1460
1460
|
}
|
|
1461
|
-
pros = pros.filter(i => i);
|
|
1462
|
-
if (pros.length > 0) {
|
|
1463
|
-
return Promise.all(pros)
|
|
1464
|
-
}
|
|
1465
1461
|
}
|
|
1466
1462
|
|
|
1467
1463
|
function hasTips(key, value) {
|
|
@@ -1497,7 +1493,7 @@ function tipsOnRmCallback(key) {
|
|
|
1497
1493
|
}
|
|
1498
1494
|
}
|
|
1499
1495
|
if (pros.length > 0) {
|
|
1500
|
-
return
|
|
1496
|
+
return Promise.all(pros);
|
|
1501
1497
|
}
|
|
1502
1498
|
}
|
|
1503
1499
|
|
|
@@ -1532,8 +1528,12 @@ async function cleanFile(path, maxChars = 9 * 1024 * 1024) {
|
|
|
1532
1528
|
}
|
|
1533
1529
|
|
|
1534
1530
|
function isPidAlive(pid) {
|
|
1531
|
+
pid = Number(pid);
|
|
1532
|
+
if (process.pid === pid) {
|
|
1533
|
+
return true;
|
|
1534
|
+
}
|
|
1535
1535
|
try {
|
|
1536
|
-
process.kill(
|
|
1536
|
+
process.kill(pid, 0); // 信号 0 不会实际发送,但会检查进程是否存在
|
|
1537
1537
|
return true; // PID 存在
|
|
1538
1538
|
} catch (err) {
|
|
1539
1539
|
if (err.code === 'ESRCH') {
|
|
@@ -2100,6 +2100,9 @@ function getValTips() {
|
|
|
2100
2100
|
}
|
|
2101
2101
|
}
|
|
2102
2102
|
let item = trim(i)
|
|
2103
|
+
if (item.startsWith("_")) {
|
|
2104
|
+
item = key;
|
|
2105
|
+
}
|
|
2103
2106
|
if (item.indexOf(',') !== -1) {
|
|
2104
2107
|
item = `[${item}]`;
|
|
2105
2108
|
}
|
|
@@ -2233,6 +2236,18 @@ const tipFns = {
|
|
|
2233
2236
|
key: tipKeys
|
|
2234
2237
|
}
|
|
2235
2238
|
|
|
2239
|
+
function currentJsir() {
|
|
2240
|
+
return JSON.parse(JSON.stringify(setting.selfJsir));
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
function currentRoom() {
|
|
2244
|
+
return JSON.parse(JSON.stringify(setting.selfRoom));
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
function currentRooms() {
|
|
2248
|
+
return JSON.parse(JSON.stringify(setting.rooms));
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2236
2251
|
module.exports = {
|
|
2237
2252
|
formatSec,
|
|
2238
2253
|
wrapperJsirText,
|
|
@@ -2350,5 +2365,8 @@ module.exports = {
|
|
|
2350
2365
|
tipFns,
|
|
2351
2366
|
getFileOpenExe,
|
|
2352
2367
|
roomConsole: createConsole(null, roomLog, roomError),
|
|
2353
|
-
formatMb
|
|
2368
|
+
formatMb,
|
|
2369
|
+
currentJsir,
|
|
2370
|
+
currentRoom,
|
|
2371
|
+
currentRooms
|
|
2354
2372
|
}
|