jsir 2.6.5 → 2.6.6
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 +39 -15
- package/deps/evalCode.js +2 -0
- package/deps/room.js +52 -58
- package/deps/setting.js +4 -2
- package/deps/util.js +101 -5
- package/package.json +1 -1
package/cmd/oaa.js
CHANGED
|
@@ -13,7 +13,7 @@ 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
|
|
16
|
+
draftModify, isRunningInBackground, fileJson, fileLock, processLock
|
|
17
17
|
} = $lib;
|
|
18
18
|
const _args = process.argv.slice(2).map(trim);
|
|
19
19
|
const evalCode = require('../deps/evalCode')
|
|
@@ -130,7 +130,8 @@ const $data = {
|
|
|
130
130
|
key: () => Object.keys(_data),
|
|
131
131
|
has: (key) => vl(_data[key]),
|
|
132
132
|
json: fileJson,
|
|
133
|
-
lock: fileLock
|
|
133
|
+
lock: fileLock,
|
|
134
|
+
pLock: processLock
|
|
134
135
|
}
|
|
135
136
|
const $homeDir = getLibDataDir()
|
|
136
137
|
|
|
@@ -703,7 +704,6 @@ async function execLibFn(fn, fnArgs) {
|
|
|
703
704
|
}
|
|
704
705
|
|
|
705
706
|
async function joinServer(uniqueName, isApi, exportLib) {
|
|
706
|
-
Room.onRoom();
|
|
707
707
|
if (!setting.serviceReg.test(uniqueName)) {
|
|
708
708
|
throw 'invalid service name';
|
|
709
709
|
}
|
|
@@ -730,6 +730,7 @@ async function joinServer(uniqueName, isApi, exportLib) {
|
|
|
730
730
|
}, isApi)
|
|
731
731
|
}
|
|
732
732
|
console.msg(uniqueName, `has become a ${isApi ? "api ":""}service.`);
|
|
733
|
+
Room.onRoom();
|
|
733
734
|
}
|
|
734
735
|
|
|
735
736
|
async function offServer(uniqueName) {
|
|
@@ -913,8 +914,10 @@ function dealStarCmd(rows, cmd, filterStr) {
|
|
|
913
914
|
let commentContent = trimText(comments.join('\n'));
|
|
914
915
|
let row = getInfo(functionContent, fnName, fnType);
|
|
915
916
|
let pair = parseUniqueName(cmd);
|
|
916
|
-
row.value =
|
|
917
|
-
|
|
917
|
+
row.value = [
|
|
918
|
+
infoStr(pair[0] + '/' + trimJsirFileName(pair[1])) + ' ' + getCmdMd5Key(parseUniqueName(cmd)[1]),
|
|
919
|
+
[commentContent, row.value].filter(i => trim(i)).join("\n")
|
|
920
|
+
].filter(i => trim(i)).join("\n");
|
|
918
921
|
rows.push(row);
|
|
919
922
|
|
|
920
923
|
resetState();
|
|
@@ -1281,6 +1284,7 @@ const keywordDef = {
|
|
|
1281
1284
|
if (!fs.existsSync(path)) {
|
|
1282
1285
|
let cmds = filterCmd(uniqueName);
|
|
1283
1286
|
if (cmds.length === 1) {
|
|
1287
|
+
uniqueName = cmds[0];
|
|
1284
1288
|
path = getFullPath(cmds[0])
|
|
1285
1289
|
} else {
|
|
1286
1290
|
console.warn("no items")
|
|
@@ -2048,6 +2052,7 @@ async function getScriptArgs(argDef, oriArgs) {
|
|
|
2048
2052
|
let argNames = Object.keys(argDef)
|
|
2049
2053
|
let exactArgs = {}
|
|
2050
2054
|
let scriptArgs = {}
|
|
2055
|
+
let argIdx = 0;
|
|
2051
2056
|
for (let i = 0; i<oriArgs.length; i++) {
|
|
2052
2057
|
let arg = oriArgs[i]
|
|
2053
2058
|
let needTrans
|
|
@@ -2079,12 +2084,13 @@ async function getScriptArgs(argDef, oriArgs) {
|
|
|
2079
2084
|
}
|
|
2080
2085
|
pair[1] = needTrans ? await evalText( 'return ' + pair[1]):pair[1]
|
|
2081
2086
|
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2087
|
+
scriptArgs["$" + argIdx] = pair[1]
|
|
2088
|
+
argIdx ++;
|
|
2089
|
+
if (argNames[i]) {
|
|
2090
|
+
scriptArgs[argNames[i]] = pair[1]
|
|
2085
2091
|
}
|
|
2086
2092
|
if (pair[0] && argNames.indexOf(pair[0]) !== -1) {
|
|
2087
|
-
delete scriptArgs[argNames[
|
|
2093
|
+
delete scriptArgs[argNames[i]]
|
|
2088
2094
|
exactArgs[pair[0]] = pair[1]
|
|
2089
2095
|
}
|
|
2090
2096
|
}
|
|
@@ -2272,7 +2278,7 @@ async function _requireSource(currSpace, cmdMatchStr, force = false) {
|
|
|
2272
2278
|
let typeKey = getJsirTypeKey(pair[1]);
|
|
2273
2279
|
if (typeKey === setting.initKey) {
|
|
2274
2280
|
let pair = parseUniqueName(uniqueName)
|
|
2275
|
-
if (
|
|
2281
|
+
if (force) {
|
|
2276
2282
|
result = await evalText(text, uniqueName)
|
|
2277
2283
|
} else {
|
|
2278
2284
|
if (setting.serviceReg.test(uniqueName)) {
|
|
@@ -2310,26 +2316,44 @@ function addErrorTag(text) {
|
|
|
2310
2316
|
let lines = text.split(/\n/);
|
|
2311
2317
|
let functionEnd = true;
|
|
2312
2318
|
let fnName = '';
|
|
2319
|
+
let wrapperFn = [];
|
|
2313
2320
|
for (let i = 0; i < lines.length; i++) {
|
|
2314
2321
|
let line = lines[i];
|
|
2315
|
-
|
|
2316
|
-
|
|
2322
|
+
if (line.startsWith("@")) {
|
|
2323
|
+
wrapperFn.push(line.substring(1).trim())
|
|
2324
|
+
result.push(null);
|
|
2325
|
+
} else {
|
|
2326
|
+
result.push(line);
|
|
2327
|
+
}
|
|
2328
|
+
let isAsyncFn = line.startsWith('async function');
|
|
2329
|
+
let isSyncFn = line.startsWith('function');
|
|
2330
|
+
if (isAsyncFn || isSyncFn) {
|
|
2317
2331
|
fnName = reget(line, /function\s+([\s\S]+)\s*\(/)
|
|
2318
2332
|
}
|
|
2319
2333
|
if (functionEnd && fnName && (/\)\s*\{$/.test(trim(line)) || (line.startsWith("{") && trim(line) === '{'))) {
|
|
2320
2334
|
result[i] += 'try{';
|
|
2335
|
+
if (wrapperFn.length > 0) {
|
|
2336
|
+
let defaultArgsList = '("'+ fnName +'")';
|
|
2337
|
+
let runner = `([${wrapperFn.map(i => 'new ' + i + (i.endsWith(")") ? '':defaultArgsList)).join(",")}],`
|
|
2338
|
+
if (isAsyncFn) {
|
|
2339
|
+
result[i] += `return await $aopAsync${runner}async ()=>{`;
|
|
2340
|
+
} else if (isSyncFn) {
|
|
2341
|
+
result[i] += `return $aop${runner}()=>{`;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2321
2344
|
functionEnd = false;
|
|
2322
2345
|
}
|
|
2323
2346
|
if (line.startsWith("}") && !functionEnd) {
|
|
2324
|
-
result[i] =
|
|
2347
|
+
result[i] = `${wrapperFn.length > 0 ? '},arguments)':''}}catch(e){throw($errorTag(e,$cmdName+'[${fnName}]'))}` + line;
|
|
2325
2348
|
functionEnd = true;
|
|
2326
2349
|
fnName = '';
|
|
2350
|
+
wrapperFn = []
|
|
2327
2351
|
}
|
|
2328
2352
|
}
|
|
2329
|
-
return result.join('\n');
|
|
2353
|
+
return result.filter(i => i !== null).join('\n');
|
|
2330
2354
|
}
|
|
2331
2355
|
|
|
2332
|
-
async function evalText($text = '', $cmdName = '', $args =
|
|
2356
|
+
async function evalText($text = '', $cmdName = '', $args = {}) {
|
|
2333
2357
|
if ($cmdName) {
|
|
2334
2358
|
console.$log(`Execute ${$cmdName}`);
|
|
2335
2359
|
}
|
package/deps/evalCode.js
CHANGED
|
@@ -20,6 +20,8 @@ module.exports = async ($text = '', $cmdName = '', $args = [],
|
|
|
20
20
|
const $setTips = $lib.setTips;
|
|
21
21
|
const $delTips = $lib.delTips;
|
|
22
22
|
const $errorTag = $lib.errorTag;
|
|
23
|
+
const $aop = $lib.aop;
|
|
24
|
+
const $aopAsync = $lib.aopAsync;
|
|
23
25
|
|
|
24
26
|
const $context = {
|
|
25
27
|
$defArgs,
|
package/deps/room.js
CHANGED
|
@@ -2,7 +2,7 @@ const os = require('os');
|
|
|
2
2
|
const {fileJson, fileLock, vl, createConsole, getKeyTips, getValTips,
|
|
3
3
|
getRoomsDir, e, isRunningInBackground,
|
|
4
4
|
batchAsync, debugStr, trim, getOr, errorTag, warnStr, getConfig, getConfigDir,
|
|
5
|
-
fileExist, formatUptime
|
|
5
|
+
fileExist, formatUptime, processLock
|
|
6
6
|
} = require('./util');
|
|
7
7
|
const {setRoute, createSign} = require('../deps/server')
|
|
8
8
|
const roomDataFile = "jsirRoom.json"
|
|
@@ -146,23 +146,21 @@ async function initNodes() {
|
|
|
146
146
|
setting.nodeMap = await fileJson("jsirNodes.json", obj => nodes);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
async function updateRoomInfo() {
|
|
149
|
+
async function updateRoomInfo(room) {
|
|
150
150
|
await initNodes();
|
|
151
151
|
let nodes = Object.keys(setting.nodeMap)
|
|
152
152
|
let ip = getSelfIP(nodes)
|
|
153
|
-
|
|
154
|
-
room
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return room;
|
|
165
|
-
})
|
|
153
|
+
room = {
|
|
154
|
+
jsirs: room.jsirs
|
|
155
|
+
}
|
|
156
|
+
// 设置roomName
|
|
157
|
+
room.name = setting.nodeMap[ip]?.name || os.hostname();
|
|
158
|
+
room.selfNode = ip;
|
|
159
|
+
room.lastUpdateTime = setting.roomTime
|
|
160
|
+
debug("init room", room.name)
|
|
161
|
+
|
|
162
|
+
await cleanRoom(room)
|
|
163
|
+
return room;
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
async function syncRooms() {
|
|
@@ -333,11 +331,11 @@ async function initRoom() {
|
|
|
333
331
|
await initRoomJsir(room)
|
|
334
332
|
if (!vl(room.lastUpdateTime) || (Date.now() - room.lastUpdateTime) > setting.roomTimer) {
|
|
335
333
|
roomUpdateTouchTime = true;
|
|
334
|
+
return await updateRoomInfo(room)
|
|
336
335
|
}
|
|
337
336
|
})
|
|
338
337
|
if (roomUpdateTouchTime) {
|
|
339
338
|
fileLock(updateRoomInfoLockKey, async () => {
|
|
340
|
-
await updateRoomInfo()
|
|
341
339
|
let pros = []
|
|
342
340
|
pros.push(syncRooms())
|
|
343
341
|
if (setting.serviceFns[setting.configMainFnKey] && !getConfig("configMain")) {
|
|
@@ -346,8 +344,8 @@ async function initRoom() {
|
|
|
346
344
|
await Promise.all(pros);
|
|
347
345
|
}, false)
|
|
348
346
|
}
|
|
349
|
-
if (defTasks) {
|
|
350
|
-
|
|
347
|
+
if (defTasks && Object.keys(defTasks).length > 0) {
|
|
348
|
+
processLock(roomTasksFile, processTasks, false)
|
|
351
349
|
}
|
|
352
350
|
await syncSetting();
|
|
353
351
|
}
|
|
@@ -505,58 +503,54 @@ async function reqNode(node, method, url, port, body) {
|
|
|
505
503
|
hostname: node,
|
|
506
504
|
port: port, // HTTP 默认端口
|
|
507
505
|
path: url,
|
|
508
|
-
method: method.toUpperCase()
|
|
509
|
-
headers: {
|
|
510
|
-
'sign': createSign()
|
|
511
|
-
}
|
|
506
|
+
method: method.toUpperCase()
|
|
512
507
|
};
|
|
513
508
|
let time = Date.now();
|
|
514
509
|
try {
|
|
515
510
|
return await new Promise((resolve, reject) => {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
});
|
|
526
|
-
// 响应结束
|
|
527
|
-
res.on('end', () => {
|
|
528
|
-
clearTimeout(timeout)
|
|
529
|
-
// 检查响应状态码
|
|
530
|
-
if (res.statusCode !== 200) {
|
|
531
|
-
reject(errorTag(new Error(data), decodeURIComponent(url)));
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
resolve(data)
|
|
535
|
-
});
|
|
511
|
+
let timeout = null
|
|
512
|
+
|
|
513
|
+
const req = http.request({...opt, headers: {
|
|
514
|
+
'sign': createSign()
|
|
515
|
+
}}, (res) => {
|
|
516
|
+
let data = '';
|
|
517
|
+
// 数据块接收
|
|
518
|
+
res.on('data', (chunk) => {
|
|
519
|
+
data += chunk;
|
|
536
520
|
});
|
|
521
|
+
// 响应结束
|
|
522
|
+
res.on('end', () => {
|
|
523
|
+
clearTimeout(timeout)
|
|
524
|
+
// 检查响应状态码
|
|
525
|
+
if (res.statusCode !== 200) {
|
|
526
|
+
reject(errorTag(new Error(data), decodeURIComponent(url)));
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
resolve(data)
|
|
530
|
+
});
|
|
531
|
+
});
|
|
537
532
|
|
|
538
|
-
|
|
533
|
+
// 设置超时逻辑
|
|
534
|
+
if (setting.reqNodeTimeouts[url]) {
|
|
539
535
|
timeout = setTimeout(() => {
|
|
540
536
|
req.destroy(); // 中断请求
|
|
541
|
-
},
|
|
542
|
-
|
|
543
|
-
// 错误处理
|
|
544
|
-
req.on('error', (e) => {
|
|
545
|
-
clearTimeout(timeout); // 清除超时定时器
|
|
546
|
-
if (room) {
|
|
547
|
-
setting.disableConnect[node + ":" + port] = Date.now() + setting.disableConnectLimit
|
|
548
|
-
}
|
|
549
|
-
reject(e)
|
|
550
|
-
});
|
|
537
|
+
}, setting.reqNodeTimeouts[url]); // 10秒超时
|
|
538
|
+
}
|
|
551
539
|
|
|
552
|
-
|
|
553
|
-
|
|
540
|
+
// 错误处理
|
|
541
|
+
req.on('error', (e) => {
|
|
542
|
+
clearTimeout(timeout); // 清除超时定时器
|
|
543
|
+
if (room) {
|
|
544
|
+
setting.disableConnect[node + ":" + port] = Date.now() + setting.disableConnectLimit
|
|
554
545
|
}
|
|
555
|
-
// 结束请求
|
|
556
|
-
req.end();
|
|
557
|
-
} catch (e) {
|
|
558
546
|
reject(e)
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
if (body) {
|
|
550
|
+
req.write(body)
|
|
559
551
|
}
|
|
552
|
+
// 结束请求
|
|
553
|
+
req.end();
|
|
560
554
|
});
|
|
561
555
|
} finally {
|
|
562
556
|
debug(`Request cost ${Date.now() - time}ms`, JSON.stringify(opt))
|
package/deps/setting.js
CHANGED
|
@@ -34,7 +34,6 @@ module.exports = {
|
|
|
34
34
|
serviceFns: {},
|
|
35
35
|
enterOutputs: null,
|
|
36
36
|
defaultPort: 52108,
|
|
37
|
-
reqNodeDefaultTimeout: 33000,
|
|
38
37
|
reqNodeTimeouts: {
|
|
39
38
|
'/': 2000
|
|
40
39
|
},
|
|
@@ -44,5 +43,8 @@ module.exports = {
|
|
|
44
43
|
roomHeartbeatExpire: 9000,
|
|
45
44
|
configMainFnKey: "config/main",
|
|
46
45
|
serviceReg: /[^a-zA-Z]service[^a-zA-Z]|[^a-zA-Z]service$/i,
|
|
47
|
-
wrapperInput: null
|
|
46
|
+
wrapperInput: null,
|
|
47
|
+
lastOutput: null,
|
|
48
|
+
locks: {},
|
|
49
|
+
lastChangeFlag: null
|
|
48
50
|
}
|
package/deps/util.js
CHANGED
|
@@ -45,7 +45,7 @@ function consoleStrs(...args) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// 格式化第一个参数
|
|
48
|
-
if (typeof args[0] === 'string') {
|
|
48
|
+
if (args.length > 1 && typeof args[0] === 'string' && hasFormat(args[0])) {
|
|
49
49
|
return util.format(...args); // 处理格式化字符串 (%s, %d 等)
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -59,6 +59,12 @@ function consoleStrs(...args) {
|
|
|
59
59
|
.join(' ');
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
// 判断是否包含格式化占位符的函数
|
|
63
|
+
function hasFormat(str) {
|
|
64
|
+
// 检查是否有 %s, %d, %j 等占位符
|
|
65
|
+
return /%[sdjifoO%]/.test(str);
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
class SyncQueue {
|
|
63
69
|
constructor() {
|
|
64
70
|
this.queue = [];
|
|
@@ -194,7 +200,7 @@ const _console =Object.assign({}, global.console);
|
|
|
194
200
|
const _consoleFns= {
|
|
195
201
|
log: {
|
|
196
202
|
fn: _console.log,
|
|
197
|
-
args: args => args
|
|
203
|
+
args: args => [consoleStrs(...args)]
|
|
198
204
|
},
|
|
199
205
|
table: {
|
|
200
206
|
fn: _console.log,
|
|
@@ -209,7 +215,7 @@ const _consoleFns= {
|
|
|
209
215
|
args: args => [infoStr('[info]'), dealLevelArgs(infoStr, args)]
|
|
210
216
|
},
|
|
211
217
|
msg: {
|
|
212
|
-
fn: _console.
|
|
218
|
+
fn: _console.info,
|
|
213
219
|
args: args => [msgStr('[msg]'), dealLevelArgs(msgStr, args)]
|
|
214
220
|
},
|
|
215
221
|
warn: {
|
|
@@ -277,6 +283,18 @@ function createConsole(uniqueName) {
|
|
|
277
283
|
if ('error' === key) {
|
|
278
284
|
global.$newError = true;
|
|
279
285
|
}
|
|
286
|
+
let hasFlag = false;
|
|
287
|
+
let sameFlag = false;
|
|
288
|
+
if (args.length > 1 && typeof args[0] === 'string' && args[0].startsWith("*") && args[0].endsWith("*")) {
|
|
289
|
+
hasFlag = true;
|
|
290
|
+
let flag = args[0]
|
|
291
|
+
args = args.slice(1)
|
|
292
|
+
|
|
293
|
+
if (!setting.lastChangeFlag || setting.lastChangeFlag === flag) {
|
|
294
|
+
sameFlag = true;
|
|
295
|
+
}
|
|
296
|
+
setting.lastChangeFlag = flag
|
|
297
|
+
}
|
|
280
298
|
if (uniqueName && quite) {
|
|
281
299
|
if ((key === 'table' || key === 'nable') && typeof args[0] === "object") {
|
|
282
300
|
args = ['', ...args]
|
|
@@ -289,7 +307,22 @@ function createConsole(uniqueName) {
|
|
|
289
307
|
}
|
|
290
308
|
} else {
|
|
291
309
|
let _args = _consoleFns[key].args(args);
|
|
310
|
+
|
|
311
|
+
if (hasFlag && !isRunningInBackground() && setting.lastOutput && sameFlag) {
|
|
312
|
+
let lines = (setting.lastOutput.match(/\n/g) || []).length + 1;
|
|
313
|
+
for (let i = 0; i < lines; i++) {
|
|
314
|
+
process.stdout.write('\x1b[A\r'+ ' '.repeat(process.stdout.columns))
|
|
315
|
+
}
|
|
316
|
+
_args[0] = '\r' + _args[0]
|
|
317
|
+
}
|
|
318
|
+
|
|
292
319
|
_consoleFns[key].fn(..._args);
|
|
320
|
+
|
|
321
|
+
if (hasFlag) {
|
|
322
|
+
setting.lastOutput = _args.join(" ");
|
|
323
|
+
} else {
|
|
324
|
+
setting.lastOutput = null;
|
|
325
|
+
}
|
|
293
326
|
}
|
|
294
327
|
}
|
|
295
328
|
}
|
|
@@ -1044,6 +1077,9 @@ function _getConfig(key, defaultVal, uniqueName) {
|
|
|
1044
1077
|
if (key === undefined) {
|
|
1045
1078
|
return config
|
|
1046
1079
|
}
|
|
1080
|
+
if (uniqueName) {
|
|
1081
|
+
console.debug(`use ${uniqueName} config "${key}"`)
|
|
1082
|
+
}
|
|
1047
1083
|
let writeFlag = false
|
|
1048
1084
|
if (!(key in config)) {
|
|
1049
1085
|
writeFlag = true
|
|
@@ -1250,7 +1286,7 @@ async function _fileLock(key, fn, expireMs = 49000) {
|
|
|
1250
1286
|
|
|
1251
1287
|
// 4. 成功加锁后执行 fn
|
|
1252
1288
|
try {
|
|
1253
|
-
await fn()
|
|
1289
|
+
await timeLimit([fn()], expireMs)
|
|
1254
1290
|
return true;
|
|
1255
1291
|
} finally {
|
|
1256
1292
|
// 5. 执行完毕后,手动释放锁目录(也可选择保留到过期自动失效,但一般都建议主动释放)
|
|
@@ -1278,6 +1314,41 @@ async function fileLock(key, fn, wait = true, expireMs = 49000) {
|
|
|
1278
1314
|
}
|
|
1279
1315
|
}
|
|
1280
1316
|
|
|
1317
|
+
async function processLock(key, fn, wait = true) {
|
|
1318
|
+
`
|
|
1319
|
+
内存锁, 默认一直等待直到加锁成功执行fn
|
|
1320
|
+
wait = false, 加锁失败则不执行fn
|
|
1321
|
+
return void
|
|
1322
|
+
`
|
|
1323
|
+
if (wait) {
|
|
1324
|
+
while (true) {
|
|
1325
|
+
if (await _processLock(key, fn)) {
|
|
1326
|
+
break;
|
|
1327
|
+
}
|
|
1328
|
+
await sleep(9);
|
|
1329
|
+
}
|
|
1330
|
+
} else {
|
|
1331
|
+
await _processLock(key, fn);
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
async function _processLock(key, fn) {
|
|
1336
|
+
if (!key || typeof fn !== 'function') {
|
|
1337
|
+
throw new Error('invalid arguments');
|
|
1338
|
+
}
|
|
1339
|
+
key = key.trim();
|
|
1340
|
+
if (setting.locks.hasOwnProperty(key)) {
|
|
1341
|
+
return false;
|
|
1342
|
+
}
|
|
1343
|
+
setting.locks[key] = true;
|
|
1344
|
+
try {
|
|
1345
|
+
await fn();
|
|
1346
|
+
return true;
|
|
1347
|
+
} finally {
|
|
1348
|
+
delete setting.locks[key];
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1281
1352
|
function removeFirst(array, obj) {
|
|
1282
1353
|
let deleteIndex
|
|
1283
1354
|
for(let i = 0;i<array.length;i++) {
|
|
@@ -2149,6 +2220,28 @@ function formatUptime() {
|
|
|
2149
2220
|
}
|
|
2150
2221
|
}
|
|
2151
2222
|
|
|
2223
|
+
function aop(items, fn, args) {
|
|
2224
|
+
let runners = [fn]
|
|
2225
|
+
let i = 0
|
|
2226
|
+
for (let item of [...items].reverse()) {
|
|
2227
|
+
const j = i;
|
|
2228
|
+
runners.push((args) => item.run(runners[j], args))
|
|
2229
|
+
i ++;
|
|
2230
|
+
}
|
|
2231
|
+
return runners[i](args)
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
async function aopAsync(items, fn, args) {
|
|
2235
|
+
let runners = [fn]
|
|
2236
|
+
let i = 0
|
|
2237
|
+
for (let item of [...items].reverse()) {
|
|
2238
|
+
const j = i;
|
|
2239
|
+
runners.push(async (args) => await item.runAsync(runners[j], args))
|
|
2240
|
+
i ++;
|
|
2241
|
+
}
|
|
2242
|
+
return await runners[i](args)
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2152
2245
|
module.exports = {
|
|
2153
2246
|
formatUptime,
|
|
2154
2247
|
wrapperJsirText,
|
|
@@ -2260,5 +2353,8 @@ module.exports = {
|
|
|
2260
2353
|
createDetachedProcess,
|
|
2261
2354
|
interceptStdStreams,
|
|
2262
2355
|
draftModify,
|
|
2263
|
-
fileExist
|
|
2356
|
+
fileExist,
|
|
2357
|
+
aop,
|
|
2358
|
+
aopAsync,
|
|
2359
|
+
processLock
|
|
2264
2360
|
}
|