jsir 2.6.14 → 3.0.1
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 +129 -98
- package/deps/evalCode.js +4 -2
- package/deps/room.js +57 -47
- package/deps/server.js +6 -13
- package/deps/setting.js +4 -1
- package/deps/util.js +236 -309
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -13,7 +13,8 @@ const {
|
|
|
13
13
|
getFullPath, parseUniqueName, toUniqueName, isJsirFileName, toJsirFileName,
|
|
14
14
|
getAlias, wrapperJsirText, eia, getKeyTips, getValTips, getJsirTypeKey,
|
|
15
15
|
createDetachedProcess, interceptStdStreams,
|
|
16
|
-
draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key, terminalTitle
|
|
16
|
+
draftModify, isRunningInBackground, fileJson, fileLock, processLock, cleanFileLocks, getMd5Key, terminalTitle,
|
|
17
|
+
getFileOpenExe, formatSec, formatMb
|
|
17
18
|
} = $lib;
|
|
18
19
|
const _args = process.argv.slice(2).map(trim);
|
|
19
20
|
const evalCode = require('../deps/evalCode')
|
|
@@ -164,20 +165,6 @@ const $data = {
|
|
|
164
165
|
}
|
|
165
166
|
const $homeDir = getLibDataDir()
|
|
166
167
|
|
|
167
|
-
function getFileOpenExe(fileName) {
|
|
168
|
-
fileName = trim(fileName);
|
|
169
|
-
let strs = fileName.split('.')
|
|
170
|
-
let suffix = ''
|
|
171
|
-
if (strs.length > 1) {
|
|
172
|
-
suffix = strs[strs.length - 1]
|
|
173
|
-
}
|
|
174
|
-
let defaultExe = getConfig("defaultExe", "open");
|
|
175
|
-
if (!suffix) {
|
|
176
|
-
return defaultExe
|
|
177
|
-
}
|
|
178
|
-
return getConfig(`${suffix}_exe`, defaultExe);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
168
|
function checkWorkspaces() {
|
|
182
169
|
let localWorkspace = _libDataDir + '/local';
|
|
183
170
|
setting.workspaceMap = {
|
|
@@ -280,7 +267,7 @@ async function watchFile(uniqueName) {
|
|
|
280
267
|
closeFileWatcher(workFilePath);
|
|
281
268
|
});
|
|
282
269
|
}
|
|
283
|
-
await
|
|
270
|
+
await eia(getFileOpenExe(), [`"${workFilePath}"`], true)
|
|
284
271
|
}
|
|
285
272
|
|
|
286
273
|
function getExeStr(oldText, newText) {
|
|
@@ -332,8 +319,8 @@ function getExeStr(oldText, newText) {
|
|
|
332
319
|
}
|
|
333
320
|
|
|
334
321
|
async function nextLine(callback, promptStr, hidden) {
|
|
335
|
-
return new Promise(resolve => {
|
|
336
|
-
_nextLine(callback, promptStr, hidden, resolve)
|
|
322
|
+
return new Promise((resolve, reject) => {
|
|
323
|
+
_nextLine(callback, promptStr, hidden, resolve, reject)
|
|
337
324
|
})
|
|
338
325
|
}
|
|
339
326
|
|
|
@@ -343,14 +330,18 @@ function defaultPromptStr(showKey = false) {
|
|
|
343
330
|
return tips;
|
|
344
331
|
}
|
|
345
332
|
|
|
346
|
-
function initRl(callback, promptStr, hidden) {
|
|
333
|
+
function initRl(callback, promptStr, hidden, reject) {
|
|
347
334
|
let origin_writeToOutput;
|
|
348
335
|
if (!_rl) {
|
|
349
336
|
_rl = readline.createInterface({
|
|
350
337
|
input: process.stdin,
|
|
351
|
-
output: process.stdout
|
|
338
|
+
output: process.stdout,
|
|
339
|
+
historySize: 1000
|
|
352
340
|
})
|
|
353
341
|
_rl.on("SIGINT", async () => {
|
|
342
|
+
if (callback !== wrapperInput) {
|
|
343
|
+
reject('Terminal Interrupt');
|
|
344
|
+
}
|
|
354
345
|
if (_noAppendNextLine) {
|
|
355
346
|
setting.promptId = Date.now();
|
|
356
347
|
await delTips();
|
|
@@ -358,7 +349,11 @@ function initRl(callback, promptStr, hidden) {
|
|
|
358
349
|
_rl._writeToOutput = origin_writeToOutput;
|
|
359
350
|
_haveWrapperInput = true;
|
|
360
351
|
_rl.clearLine(0)
|
|
361
|
-
|
|
352
|
+
if (callback === wrapperInput) {
|
|
353
|
+
nextLine();
|
|
354
|
+
} else {
|
|
355
|
+
closeRl()
|
|
356
|
+
}
|
|
362
357
|
}
|
|
363
358
|
});
|
|
364
359
|
_rl.history = _rlHistory
|
|
@@ -408,19 +403,19 @@ function closeRl() {
|
|
|
408
403
|
_rl = null;
|
|
409
404
|
}
|
|
410
405
|
|
|
411
|
-
function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
406
|
+
function _nextLine(callback, promptStr, hidden, resolve, reject, end, isText) {
|
|
412
407
|
callback = callback || wrapperInput;
|
|
413
408
|
if (!setting.enableNextLine) {
|
|
414
|
-
console.$
|
|
409
|
+
console.$warn("NextLine Disabled");
|
|
415
410
|
resolve(null);
|
|
416
411
|
return;
|
|
417
412
|
}
|
|
418
413
|
if (!_haveWrapperInput) {
|
|
419
|
-
console.$error(
|
|
414
|
+
console.$error("NextLine Blocked");
|
|
420
415
|
resolve(null);
|
|
421
416
|
return;
|
|
422
417
|
}
|
|
423
|
-
initRl(callback, promptStr, hidden);
|
|
418
|
+
initRl(callback, promptStr, hidden, reject);
|
|
424
419
|
if (callback !== wrapperInput) {
|
|
425
420
|
_haveWrapperInput = false
|
|
426
421
|
}
|
|
@@ -439,7 +434,7 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
|
439
434
|
} else {
|
|
440
435
|
inputs.push(line)
|
|
441
436
|
}
|
|
442
|
-
if (trim(textLine) && (hidden ||
|
|
437
|
+
if (trim(textLine) && (hidden || isText)) {
|
|
443
438
|
_rl.history = _rl.history.slice(1)
|
|
444
439
|
}
|
|
445
440
|
if (!isText || line === end) {
|
|
@@ -473,13 +468,13 @@ function _nextLine(callback, promptStr, hidden, resolve, end, isText) {
|
|
|
473
468
|
_rl.prompt()
|
|
474
469
|
if (callback === wrapperInput) {
|
|
475
470
|
setting.promptId = Date.now();
|
|
471
|
+
setting.lastOutput = null;
|
|
476
472
|
}
|
|
477
|
-
setting.lastOutput = null;
|
|
478
473
|
}
|
|
479
474
|
|
|
480
475
|
async function nextText(callback, end, hidden) {
|
|
481
|
-
return new Promise(resolve => {
|
|
482
|
-
_nextLine(callback, '', hidden, resolve, end, true)
|
|
476
|
+
return new Promise((resolve, reject) => {
|
|
477
|
+
_nextLine(callback, '', hidden, resolve, reject, end, true)
|
|
483
478
|
})
|
|
484
479
|
}
|
|
485
480
|
|
|
@@ -755,7 +750,7 @@ async function execLibFn(fn, fnArgs) {
|
|
|
755
750
|
|
|
756
751
|
async function joinServer(uniqueName, isApi, exportLib) {
|
|
757
752
|
if (!setting.serviceReg.test(uniqueName)) {
|
|
758
|
-
|
|
753
|
+
return;
|
|
759
754
|
}
|
|
760
755
|
let asyncFnSize = 0
|
|
761
756
|
for (let key of Object.keys(exportLib)) {
|
|
@@ -785,7 +780,7 @@ async function joinServer(uniqueName, isApi, exportLib) {
|
|
|
785
780
|
|
|
786
781
|
async function offServer(uniqueName) {
|
|
787
782
|
if (!setting.serviceReg.test(uniqueName)) {
|
|
788
|
-
|
|
783
|
+
return;
|
|
789
784
|
}
|
|
790
785
|
let pair = parseUniqueName(uniqueName)
|
|
791
786
|
let service = `${pair[0]}/${trimJsirFileName(pair[1])}`;
|
|
@@ -1044,29 +1039,6 @@ function help(filterFn) {
|
|
|
1044
1039
|
}))
|
|
1045
1040
|
}
|
|
1046
1041
|
|
|
1047
|
-
function delTipsByIndex(idxs) {
|
|
1048
|
-
let keys = Object.keys(setting.tips)
|
|
1049
|
-
let indexKeyMap = {}
|
|
1050
|
-
for(let i = 1;i<=keys.length;i++) {
|
|
1051
|
-
indexKeyMap[i] = keys[i - 1]
|
|
1052
|
-
}
|
|
1053
|
-
let params = []
|
|
1054
|
-
for (const index of idxs) {
|
|
1055
|
-
if (setting.tips.hasOwnProperty(index)) {
|
|
1056
|
-
params.push(index)
|
|
1057
|
-
} else if (indexKeyMap[Number(index)]) {
|
|
1058
|
-
params.push(indexKeyMap[Number(index)])
|
|
1059
|
-
} else if (indexKeyMap[keys.length + 1 + Number(index)]) {
|
|
1060
|
-
params.push(indexKeyMap[keys.length + 1 + Number(index)])
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
if (idxs.length > 0 && params.length <= 0) {
|
|
1064
|
-
console.warn("no items")
|
|
1065
|
-
return;
|
|
1066
|
-
}
|
|
1067
|
-
return delTips(...params)
|
|
1068
|
-
}
|
|
1069
|
-
|
|
1070
1042
|
function getPackageVersion(space, name) {
|
|
1071
1043
|
let moduleDir = setting.workspaceMap[space] + '/node_modules'
|
|
1072
1044
|
let dir = moduleDir + "/" + name;
|
|
@@ -1158,26 +1130,28 @@ async function showRooms() {
|
|
|
1158
1130
|
for (let i = 0; i < setting.rooms.length; i++) {
|
|
1159
1131
|
let room = setting.rooms[i]
|
|
1160
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"):"";
|
|
1161
1135
|
results.push({
|
|
1162
|
-
name: (isLocal ? "*" : " ") +
|
|
1136
|
+
name: (isLocal ? infoStr("*") : " ") + roomName,
|
|
1163
1137
|
node: room.selfNode,
|
|
1164
|
-
|
|
1138
|
+
delay: delayStr
|
|
1165
1139
|
})
|
|
1166
1140
|
for (let key of Object.keys(room.jsirs)) {
|
|
1167
1141
|
let jsir = room.jsirs[key]
|
|
1168
|
-
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));
|
|
1169
1143
|
results.push({
|
|
1170
|
-
name: (isLocal ? "*" : " ") +
|
|
1144
|
+
name: (isLocal ? infoStr("*") : " ") + roomName,
|
|
1171
1145
|
node: room.selfNode,
|
|
1172
|
-
|
|
1173
|
-
pid:
|
|
1174
|
-
up: jsir.upTime || '',
|
|
1146
|
+
delay: delayStr,
|
|
1147
|
+
pid: pidStr,
|
|
1148
|
+
up: formatSec(jsir.upTime) || '',
|
|
1175
1149
|
version: jsir.version || '',
|
|
1176
1150
|
space: jsir.space,
|
|
1177
|
-
running: jsir.active,
|
|
1178
1151
|
port: jsir.port,
|
|
1179
1152
|
back: jsir.back,
|
|
1180
1153
|
busy: jsir.busy,
|
|
1154
|
+
mem: formatMb(jsir.mem) || '',
|
|
1181
1155
|
tips: Object.keys(jsir.tips).map(i => infoStr(i) + ': ' + jsir.tips[i]).join('\n'),
|
|
1182
1156
|
services: Object.keys(jsir.services || []).map(msgStr).join('\n')
|
|
1183
1157
|
});
|
|
@@ -1211,7 +1185,24 @@ const keywordDef = {
|
|
|
1211
1185
|
clear: {
|
|
1212
1186
|
comment: 'Clear task',
|
|
1213
1187
|
exeFn: async (args) => {
|
|
1214
|
-
|
|
1188
|
+
if (args.length > 0 && _cmdMap[args[0]]) {
|
|
1189
|
+
let cmdName = _cmdMap[args[0]];
|
|
1190
|
+
if (args.length === 1) {
|
|
1191
|
+
$data.del(cmdName)
|
|
1192
|
+
} else {
|
|
1193
|
+
let metadata = $data.get(cmdName);
|
|
1194
|
+
if (!vl(metadata) || typeof metadata !== 'object') {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1197
|
+
for (let key of args.slice(1)) {
|
|
1198
|
+
if (metadata.hasOwnProperty(key)) {
|
|
1199
|
+
delete metadata[key]
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
} else {
|
|
1204
|
+
await delTips(...args)
|
|
1205
|
+
}
|
|
1215
1206
|
},
|
|
1216
1207
|
args: {
|
|
1217
1208
|
tipIndex: 'left prompt index, can be separated by spaces for multiple'
|
|
@@ -1303,7 +1294,7 @@ const keywordDef = {
|
|
|
1303
1294
|
console.warn("no items")
|
|
1304
1295
|
} else {
|
|
1305
1296
|
let path = getFullPath(uniqueName)
|
|
1306
|
-
await eia(getEditor(), [path])
|
|
1297
|
+
await eia(getEditor(), [`"${path}"`], true)
|
|
1307
1298
|
}
|
|
1308
1299
|
},
|
|
1309
1300
|
args: {
|
|
@@ -1332,12 +1323,22 @@ const keywordDef = {
|
|
|
1332
1323
|
console.msg("config service offline")
|
|
1333
1324
|
} else if (_cmdMap[args[0]]){
|
|
1334
1325
|
let uniqueName = _cmdMap[args[0]];
|
|
1335
|
-
|
|
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
|
+
}
|
|
1336
1332
|
} else {
|
|
1337
1333
|
console.warn('invalid args')
|
|
1338
1334
|
}
|
|
1339
1335
|
} else {
|
|
1340
|
-
|
|
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
|
+
}
|
|
1341
1342
|
}
|
|
1342
1343
|
},
|
|
1343
1344
|
short: 's'
|
|
@@ -1349,18 +1350,24 @@ const keywordDef = {
|
|
|
1349
1350
|
if (!uniqueName) {
|
|
1350
1351
|
console.warn("no items")
|
|
1351
1352
|
} else {
|
|
1352
|
-
let
|
|
1353
|
-
if (
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1353
|
+
let names = [uniqueName]
|
|
1354
|
+
if (uniqueName === 'ALL') {
|
|
1355
|
+
names = Object.values(_cmdMap)
|
|
1356
|
+
}
|
|
1357
|
+
for (let uniqueName of names) {
|
|
1358
|
+
let path = getFullPath(uniqueName)
|
|
1359
|
+
if (!fs.existsSync(path)) {
|
|
1360
|
+
let cmds = filterCmd(uniqueName);
|
|
1361
|
+
if (cmds.length === 1) {
|
|
1362
|
+
uniqueName = cmds[0];
|
|
1363
|
+
path = getFullPath(cmds[0])
|
|
1364
|
+
} else {
|
|
1365
|
+
console.warn("no items")
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1361
1368
|
}
|
|
1369
|
+
await eia(getFileOpenExe(), [`"${path}"`], true)
|
|
1362
1370
|
}
|
|
1363
|
-
await e(`"${getFileOpenExe(parseUniqueName(uniqueName)[1])}" "${path}"`)
|
|
1364
1371
|
}
|
|
1365
1372
|
},
|
|
1366
1373
|
args: {
|
|
@@ -1377,7 +1384,7 @@ const keywordDef = {
|
|
|
1377
1384
|
let bSpace = args[1]
|
|
1378
1385
|
|
|
1379
1386
|
if (aUniqueName && bUniqueName) {
|
|
1380
|
-
let result = await
|
|
1387
|
+
let result = await eia(getConfig("compareExe", "diff"), [`"${getFullPath(aUniqueName)}"`, `"${getFullPath(bUniqueName)}"`], true)
|
|
1381
1388
|
if (result) {
|
|
1382
1389
|
console.log(result)
|
|
1383
1390
|
}
|
|
@@ -1709,6 +1716,10 @@ const keywordDef = {
|
|
|
1709
1716
|
if (setting.selfRoom.selfNode === room.selfNode && String(process.pid) === pid) {
|
|
1710
1717
|
continue;
|
|
1711
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
|
+
}
|
|
1712
1723
|
have = true;
|
|
1713
1724
|
tasks.push(async (input) => {
|
|
1714
1725
|
let jsir = room.jsirs[pid];
|
|
@@ -1907,26 +1918,36 @@ function getComments(i, cmdName, text, cols = [], col) {
|
|
|
1907
1918
|
let docLines = [getMd5Key(parseUniqueName(cmdName)[1]) + " - " + i]
|
|
1908
1919
|
text = trim(text)
|
|
1909
1920
|
docLines.push(...getTextComments(text))
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
})
|
|
1921
|
-
if (docLines.length > 2) {
|
|
1922
|
-
for (let line of docLines.slice(2)) {
|
|
1923
|
-
cols.push({
|
|
1924
|
-
doc: ' ' + line
|
|
1925
|
-
})
|
|
1926
|
-
}
|
|
1921
|
+
col.doc = '- ' + docLines[0]
|
|
1922
|
+
if (docLines.length > 1) {
|
|
1923
|
+
cols.push({
|
|
1924
|
+
doc: ' ' + infoStr(docLines[1])
|
|
1925
|
+
})
|
|
1926
|
+
if (docLines.length > 2) {
|
|
1927
|
+
for (let line of docLines.slice(2)) {
|
|
1928
|
+
cols.push({
|
|
1929
|
+
doc: ' ' + line
|
|
1930
|
+
})
|
|
1927
1931
|
}
|
|
1928
1932
|
}
|
|
1929
1933
|
}
|
|
1934
|
+
|
|
1935
|
+
// 处理参数
|
|
1936
|
+
let argDef = getArgDef(text, cmdName)
|
|
1937
|
+
let comments = getArgComments(argDef, true)
|
|
1938
|
+
for (let line of comments) {
|
|
1939
|
+
cols.push({
|
|
1940
|
+
doc: ' ' + line
|
|
1941
|
+
})
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
// 处理元数据
|
|
1945
|
+
let metadata = $data.get(cmdName);
|
|
1946
|
+
if (vl(metadata) && typeof metadata === 'object' && Object.keys(metadata).length > 0) {
|
|
1947
|
+
cols.push({
|
|
1948
|
+
doc: ' ' + Object.keys(metadata).map(msgStr).join(' / ')
|
|
1949
|
+
})
|
|
1950
|
+
}
|
|
1930
1951
|
}
|
|
1931
1952
|
|
|
1932
1953
|
function trimJsirFileName(name) {
|
|
@@ -2428,17 +2449,27 @@ function _addErrorTag(lines) {
|
|
|
2428
2449
|
} else {
|
|
2429
2450
|
result.push(line);
|
|
2430
2451
|
}
|
|
2431
|
-
let isAsyncFn = line.startsWith('async function');
|
|
2432
|
-
let isSyncFn = line.startsWith('function');
|
|
2452
|
+
let isAsyncFn = line.startsWith('async function ');
|
|
2453
|
+
let isSyncFn = line.startsWith('function ');
|
|
2433
2454
|
if (isAsyncFn || isSyncFn) {
|
|
2434
|
-
fnName = reget(line, /function\s+([
|
|
2455
|
+
fnName = reget(line, /function\s+([a-zA-Z_$][a-zA-Z0-9_$.]*)\s*\(/)
|
|
2435
2456
|
fnIsAsync = isAsyncFn;
|
|
2436
2457
|
}
|
|
2437
2458
|
if (functionEnd && fnName && (/\)\s*\{$/.test(trim(line)) || (line.startsWith("{") && trim(line) === '{'))) {
|
|
2438
2459
|
result[i] += 'try{';
|
|
2439
2460
|
if (wrapperFn.length > 0) {
|
|
2440
2461
|
let defaultArgsList = '("'+ fnName +'")';
|
|
2441
|
-
let runner = `([${wrapperFn.map(i =>
|
|
2462
|
+
let runner = `([${wrapperFn.map(i => {
|
|
2463
|
+
if (i.endsWith(")")) {
|
|
2464
|
+
i = i
|
|
2465
|
+
.replace(/^([^(]+)\(\s*null\s*/, '$1("'+ fnName + '"')
|
|
2466
|
+
.replace(/^([^(]+)\(\s*undefined\s*/, '$1("'+ fnName + '"')
|
|
2467
|
+
.replace(/^([^(]+)\(\s*\)/, '$1' + defaultArgsList)
|
|
2468
|
+
} else {
|
|
2469
|
+
i += defaultArgsList;
|
|
2470
|
+
}
|
|
2471
|
+
return 'new ' + i;
|
|
2472
|
+
}).join(",")}],`
|
|
2442
2473
|
if (fnIsAsync) {
|
|
2443
2474
|
result[i] += `return await $aopAsync${runner}async ()=>{`;
|
|
2444
2475
|
} else {
|
package/deps/evalCode.js
CHANGED
|
@@ -17,10 +17,12 @@ module.exports = async ($text = '', $cmdName = '', $args = [],
|
|
|
17
17
|
// 兼容
|
|
18
18
|
$text = $lib.wrapperJsirText($text)
|
|
19
19
|
|
|
20
|
-
const $setTips = $lib.setTips;
|
|
21
|
-
const $delTips = $lib.delTips;
|
|
22
20
|
const $tips = $lib.tipFns;
|
|
23
21
|
const $errorTag = $lib.errorTag;
|
|
22
|
+
|
|
23
|
+
// 不在context中
|
|
24
|
+
const $setTips = $lib.setTips;
|
|
25
|
+
const $delTips = $lib.delTips;
|
|
24
26
|
const $aop = $lib.aop;
|
|
25
27
|
const $aopAsync = $lib.aopAsync;
|
|
26
28
|
|
package/deps/room.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const os = require('os');
|
|
2
|
-
const {fileJson, fileLock, vl,
|
|
2
|
+
const {fileJson, fileLock, vl, getKeyTips, getValTips,
|
|
3
3
|
getRoomsDir, e, isRunningInBackground,
|
|
4
|
-
batchAsync,
|
|
5
|
-
fileExist,
|
|
4
|
+
batchAsync, trim, getOr, errorTag, warnStr, getConfig, getConfigDir,
|
|
5
|
+
fileExist, processLock, isPidAlive, cleanFileLocks,
|
|
6
|
+
roomConsole: console, reget
|
|
6
7
|
} = require('./util');
|
|
7
8
|
const {setRoute, createSign} = require('../deps/server')
|
|
8
9
|
const roomDataFile = "jsirRoom.json"
|
|
@@ -10,20 +11,12 @@ const jsirNodesFile = "jsirNodes.json"
|
|
|
10
11
|
const roomTasksFile = "roomTasks.json"
|
|
11
12
|
const roomsDirLockKey = "RW_" + getRoomsDir();
|
|
12
13
|
const updateRoomInfoLockKey = "UPDATE_" + roomDataFile
|
|
13
|
-
const console = createConsole();
|
|
14
14
|
const setting = require('../deps/setting')
|
|
15
15
|
const fp = require('fs').promises
|
|
16
16
|
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
|
-
|
|
22
|
-
function debug(...args) {
|
|
23
|
-
if (global.$DEBUG) {
|
|
24
|
-
console.$log(debugStr('[debug]'), ...args);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
20
|
|
|
28
21
|
async function localConfigs() {
|
|
29
22
|
let configDir = getConfigDir();
|
|
@@ -61,7 +54,7 @@ function onRoom() {
|
|
|
61
54
|
}
|
|
62
55
|
})
|
|
63
56
|
} catch (e) {
|
|
64
|
-
debug("initRoute failed", e)
|
|
57
|
+
console.$debug("initRoute failed", e)
|
|
65
58
|
}
|
|
66
59
|
_onRoom();
|
|
67
60
|
}
|
|
@@ -72,7 +65,7 @@ function _onRoom() {
|
|
|
72
65
|
try {
|
|
73
66
|
await initRoom();
|
|
74
67
|
} catch (e) {
|
|
75
|
-
debug('initRoom', e)
|
|
68
|
+
console.$debug('initRoom', e)
|
|
76
69
|
}
|
|
77
70
|
if (setting.roomTid[0]) {
|
|
78
71
|
_onRoom();
|
|
@@ -86,7 +79,7 @@ function offRoom() {
|
|
|
86
79
|
setting.roomTid[0] = null
|
|
87
80
|
if (setting.server) {
|
|
88
81
|
setting.server.close(() => {
|
|
89
|
-
debug('Existing server shut down.');
|
|
82
|
+
console.$debug('Existing server shut down.');
|
|
90
83
|
});
|
|
91
84
|
}
|
|
92
85
|
}
|
|
@@ -117,7 +110,7 @@ async function initNodes() {
|
|
|
117
110
|
try {
|
|
118
111
|
resp = await e(`${tailscalePath} status`);
|
|
119
112
|
} catch (e) {
|
|
120
|
-
debug("initNodes", e)
|
|
113
|
+
console.$debug("initNodes", e)
|
|
121
114
|
}
|
|
122
115
|
for (let line of resp.split("\n").map(trim)) {
|
|
123
116
|
let offline = line.indexOf('offline') !== -1
|
|
@@ -145,7 +138,7 @@ async function updateRoomInfo(room) {
|
|
|
145
138
|
room.name = setting.nodeMap[ip]?.name || os.hostname();
|
|
146
139
|
room.selfNode = ip;
|
|
147
140
|
room.lastUpdateTime = setting.roomTime
|
|
148
|
-
debug("init room", room.name)
|
|
141
|
+
console.$debug("init room", room.name)
|
|
149
142
|
|
|
150
143
|
await cleanRoom(room)
|
|
151
144
|
return room;
|
|
@@ -167,10 +160,11 @@ async function syncRooms() {
|
|
|
167
160
|
fns.push(async () => {
|
|
168
161
|
let respBody = ''
|
|
169
162
|
try {
|
|
163
|
+
let begin = Date.now();
|
|
170
164
|
try {
|
|
171
165
|
respBody = await reqNode(node, "get", "/");
|
|
172
166
|
} catch (e) {
|
|
173
|
-
debug(`sync ${node} failed:`, e);
|
|
167
|
+
console.$debug(`sync ${node} failed:`, e);
|
|
174
168
|
if (!isDisableConnect(node, setting.defaultPort)) {
|
|
175
169
|
respBody = await reqNode(node, "get", "/", setting.defaultPort);
|
|
176
170
|
}
|
|
@@ -184,11 +178,12 @@ async function syncRooms() {
|
|
|
184
178
|
Object.entries(currRoom.jsirs || {}).filter(([pid, jsir]) => jsir.port === setting.defaultPort)
|
|
185
179
|
);
|
|
186
180
|
}
|
|
181
|
+
currRoom.delay = Date.now() - begin;
|
|
187
182
|
syncRooms.push(currRoom)
|
|
188
|
-
debug(`sync ${node} success`);
|
|
183
|
+
console.$debug(`sync ${node} success`);
|
|
189
184
|
}
|
|
190
185
|
} catch (e) {
|
|
191
|
-
debug(`sync ${node} failed:`, respBody, e);
|
|
186
|
+
console.$debug(`sync ${node} failed:`, respBody, e);
|
|
192
187
|
}
|
|
193
188
|
})
|
|
194
189
|
}
|
|
@@ -208,11 +203,11 @@ async function syncRooms() {
|
|
|
208
203
|
try {
|
|
209
204
|
await fp.unlink(roomsDir + '/' + file)
|
|
210
205
|
} catch (e) {
|
|
211
|
-
debug(e);
|
|
206
|
+
console.$debug(e);
|
|
212
207
|
}
|
|
213
208
|
}
|
|
214
209
|
}
|
|
215
|
-
debug('syncRooms done')
|
|
210
|
+
console.$debug('syncRooms done')
|
|
216
211
|
}
|
|
217
212
|
|
|
218
213
|
async function syncSetting() {
|
|
@@ -278,32 +273,45 @@ async function _syncSetting(room) {
|
|
|
278
273
|
}
|
|
279
274
|
}
|
|
280
275
|
|
|
281
|
-
async function processTasks() {
|
|
276
|
+
async function processTasks(defTasks) {
|
|
282
277
|
await fileJson(roomTasksFile, async tasks => {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
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
|
+
}
|
|
288
290
|
}
|
|
291
|
+
|
|
289
292
|
let unHandleKey = null;
|
|
290
293
|
for (let key of Object.keys(defTasks)) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (key.indexOf("*") === -1 && setting.defaultPort === setting.selfJsir.port) {
|
|
296
|
-
continue;
|
|
297
|
-
}
|
|
298
|
-
unHandleKey = key
|
|
299
|
-
break;
|
|
294
|
+
let isMainPid = setting.defaultPort === setting.selfJsir.port;
|
|
295
|
+
let isMainTask = key.includes("*");
|
|
296
|
+
if (isMainPid !== isMainTask) {
|
|
297
|
+
continue;
|
|
300
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;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
unHandleKey = key;
|
|
301
308
|
}
|
|
302
309
|
if (unHandleKey) {
|
|
303
310
|
console.$log(process.pid, `run task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
304
311
|
await setting.wrapperInput(defTasks[unHandleKey]);
|
|
305
312
|
if (!setting.newError) {
|
|
306
|
-
|
|
313
|
+
let taskKey = trim(trim(unHandleKey).replace(/\d+$/, ''));
|
|
314
|
+
tasks[taskKey] = [...(tasks[taskKey] || []), process.pid];
|
|
307
315
|
console.$log(process.pid, `handle task ${unHandleKey}[${defTasks[unHandleKey]}]`)
|
|
308
316
|
}
|
|
309
317
|
}
|
|
@@ -333,10 +341,11 @@ async function initRoom() {
|
|
|
333
341
|
pros.push(syncConfigs())
|
|
334
342
|
}
|
|
335
343
|
await Promise.all(pros);
|
|
336
|
-
}, false).catch(debug)
|
|
344
|
+
}, false).catch(console.$debug)
|
|
337
345
|
}
|
|
346
|
+
const defTasks = getConfig("tasks");
|
|
338
347
|
if (defTasks && Object.keys(defTasks).length > 0) {
|
|
339
|
-
processLock(roomTasksFile, processTasks, false).catch(debug)
|
|
348
|
+
processLock(roomTasksFile, () => processTasks(defTasks), false).catch(console.$debug)
|
|
340
349
|
}
|
|
341
350
|
await syncSetting();
|
|
342
351
|
}
|
|
@@ -346,7 +355,7 @@ async function syncConfigs() {
|
|
|
346
355
|
try {
|
|
347
356
|
configs = await reqFn(setting.configMainFnKey);
|
|
348
357
|
} catch (e) {
|
|
349
|
-
debug("syncConfigs failed", e)
|
|
358
|
+
console.$debug("syncConfigs failed", e)
|
|
350
359
|
return;
|
|
351
360
|
}
|
|
352
361
|
let configDir = getConfigDir();
|
|
@@ -359,16 +368,16 @@ async function syncConfigs() {
|
|
|
359
368
|
let currText = String(await fp.readFile(path));
|
|
360
369
|
if (currText !== text) {
|
|
361
370
|
await fp.writeFile(path, text)
|
|
362
|
-
debug(`sync ${key} success`);
|
|
371
|
+
console.$debug(`sync ${key} success`);
|
|
363
372
|
}
|
|
364
373
|
} else {
|
|
365
374
|
await fp.writeFile(path, text)
|
|
366
|
-
debug(`sync ${key} success`);
|
|
375
|
+
console.$debug(`sync ${key} success`);
|
|
367
376
|
}
|
|
368
377
|
});
|
|
369
378
|
}
|
|
370
379
|
await batchAsync(fns, 33)
|
|
371
|
-
debug('syncConfigs done')
|
|
380
|
+
console.$debug('syncConfigs done')
|
|
372
381
|
}
|
|
373
382
|
|
|
374
383
|
async function cleanRoom(room) {
|
|
@@ -378,10 +387,10 @@ async function cleanRoom(room) {
|
|
|
378
387
|
let active = Date.now() - (jsir.lastUpdateTime || 0) <= setting.roomHeartbeatExpire;
|
|
379
388
|
if (jsir.back && !active && isPidAlive(pid)) {
|
|
380
389
|
try {
|
|
381
|
-
debug(`kill inactive jsir ${pid}`)
|
|
390
|
+
console.$debug(`kill inactive jsir ${pid}`)
|
|
382
391
|
process.kill(parseInt(pid), 'SIGKILL'); // 强制终止进程
|
|
383
392
|
} catch (e) {
|
|
384
|
-
debug(`cleanRoom ${pid} failed`, e)
|
|
393
|
+
console.$debug(`cleanRoom ${pid} failed`, e)
|
|
385
394
|
}
|
|
386
395
|
}
|
|
387
396
|
}
|
|
@@ -438,7 +447,8 @@ async function initRoomJsir(room) {
|
|
|
438
447
|
services: services,
|
|
439
448
|
newError: setting.newError,
|
|
440
449
|
version: packageJson.version,
|
|
441
|
-
upTime:
|
|
450
|
+
upTime: process.uptime(),
|
|
451
|
+
mem: Math.floor(process.memoryUsage().rss / 1024 / 1024)
|
|
442
452
|
}
|
|
443
453
|
room.jsirs[process.pid] = setting.selfJsir
|
|
444
454
|
}
|
|
@@ -547,7 +557,7 @@ async function reqNode(node, method, url, port, body) {
|
|
|
547
557
|
req.end();
|
|
548
558
|
});
|
|
549
559
|
} finally {
|
|
550
|
-
debug(`Request cost ${Date.now() - time}ms`, JSON.stringify(opt))
|
|
560
|
+
console.$debug(`Request cost ${Date.now() - time}ms`, JSON.stringify(opt))
|
|
551
561
|
}
|
|
552
562
|
}
|
|
553
563
|
|