@andersbakken/fisk 4.0.62 → 4.0.64
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/builder/VM_runtime.js +45 -42
- package/builder/fisk-builder.js +17480 -12580
- package/daemon/fisk-daemon.js +231 -36
- package/monitor/fisk-monitor.js +635 -123
- package/package.json +1 -1
- package/scheduler/fisk-scheduler.js +9109 -5225
package/daemon/fisk-daemon.js
CHANGED
|
@@ -7,10 +7,10 @@ var require$$0 = require('constants');
|
|
|
7
7
|
var require$$0$1 = require('stream');
|
|
8
8
|
var require$$4 = require('util');
|
|
9
9
|
var assert$1 = require('assert');
|
|
10
|
-
var
|
|
10
|
+
var path$h = require('path');
|
|
11
11
|
var os$1 = require('os');
|
|
12
12
|
var net = require('net');
|
|
13
|
-
var require$$1$
|
|
13
|
+
var require$$1$1 = require('module');
|
|
14
14
|
|
|
15
15
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
16
16
|
|
|
@@ -20,10 +20,10 @@ var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
|
|
|
20
20
|
var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$1);
|
|
21
21
|
var require$$4__default = /*#__PURE__*/_interopDefaultLegacy(require$$4);
|
|
22
22
|
var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert$1);
|
|
23
|
-
var
|
|
23
|
+
var path__default = /*#__PURE__*/_interopDefaultLegacy(path$h);
|
|
24
24
|
var os__default = /*#__PURE__*/_interopDefaultLegacy(os$1);
|
|
25
25
|
var net__default = /*#__PURE__*/_interopDefaultLegacy(net);
|
|
26
|
-
var require$$1__default$
|
|
26
|
+
var require$$1__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$1$1);
|
|
27
27
|
|
|
28
28
|
const Constants = {
|
|
29
29
|
// client codes
|
|
@@ -42,6 +42,12 @@ const Constants = {
|
|
|
42
42
|
get JSON() {
|
|
43
43
|
return 5;
|
|
44
44
|
},
|
|
45
|
+
get AcquireSlot() {
|
|
46
|
+
return 6;
|
|
47
|
+
},
|
|
48
|
+
get ReleaseLocalSlot() {
|
|
49
|
+
return 7;
|
|
50
|
+
},
|
|
45
51
|
// daemon codes
|
|
46
52
|
get CppSlotAcquired() {
|
|
47
53
|
return 10;
|
|
@@ -51,6 +57,9 @@ const Constants = {
|
|
|
51
57
|
},
|
|
52
58
|
get JSONResponse() {
|
|
53
59
|
return 12;
|
|
60
|
+
},
|
|
61
|
+
get LocalSlotAcquired() {
|
|
62
|
+
return 13;
|
|
54
63
|
}
|
|
55
64
|
};
|
|
56
65
|
|
|
@@ -208,6 +217,12 @@ class Compile extends EventEmitter__default["default"] {
|
|
|
208
217
|
case Constants.ReleaseCompileSlot:
|
|
209
218
|
emit("releaseCompileSlot");
|
|
210
219
|
continue;
|
|
220
|
+
case Constants.AcquireSlot:
|
|
221
|
+
emit("acquireSlot");
|
|
222
|
+
continue;
|
|
223
|
+
case Constants.ReleaseLocalSlot:
|
|
224
|
+
emit("releaseLocalSlot");
|
|
225
|
+
continue;
|
|
211
226
|
case Constants.JSON:
|
|
212
227
|
if (available < 5) {
|
|
213
228
|
break;
|
|
@@ -1332,7 +1347,7 @@ function retry () {
|
|
|
1332
1347
|
};
|
|
1333
1348
|
} (fs$j));
|
|
1334
1349
|
|
|
1335
|
-
const path$g =
|
|
1350
|
+
const path$g = path__default["default"];
|
|
1336
1351
|
|
|
1337
1352
|
// get drive on windows
|
|
1338
1353
|
function getRootPath (p) {
|
|
@@ -1357,7 +1372,7 @@ var win32 = {
|
|
|
1357
1372
|
};
|
|
1358
1373
|
|
|
1359
1374
|
const fs$h = gracefulFs;
|
|
1360
|
-
const path$f =
|
|
1375
|
+
const path$f = path__default["default"];
|
|
1361
1376
|
const invalidWin32Path$1 = win32.invalidWin32Path;
|
|
1362
1377
|
|
|
1363
1378
|
const o777$1 = parseInt('0777', 8);
|
|
@@ -1419,7 +1434,7 @@ function mkdirs$2 (p, opts, callback, made) {
|
|
|
1419
1434
|
var mkdirs_1$1 = mkdirs$2;
|
|
1420
1435
|
|
|
1421
1436
|
const fs$g = gracefulFs;
|
|
1422
|
-
const path$e =
|
|
1437
|
+
const path$e = path__default["default"];
|
|
1423
1438
|
const invalidWin32Path = win32.invalidWin32Path;
|
|
1424
1439
|
|
|
1425
1440
|
const o777 = parseInt('0777', 8);
|
|
@@ -1487,7 +1502,7 @@ var mkdirs_1 = {
|
|
|
1487
1502
|
|
|
1488
1503
|
const fs$f = gracefulFs;
|
|
1489
1504
|
const os = os__default["default"];
|
|
1490
|
-
const path$d =
|
|
1505
|
+
const path$d = path__default["default"];
|
|
1491
1506
|
|
|
1492
1507
|
// HFS, ext{2,3}, FAT do not, Node.js v0.10 does not
|
|
1493
1508
|
function hasMillisResSync () {
|
|
@@ -1576,7 +1591,7 @@ var buffer$1 = function (size) {
|
|
|
1576
1591
|
};
|
|
1577
1592
|
|
|
1578
1593
|
const fs$e = gracefulFs;
|
|
1579
|
-
const path$c =
|
|
1594
|
+
const path$c = path__default["default"];
|
|
1580
1595
|
const mkdirpSync$1 = mkdirs_1.mkdirsSync;
|
|
1581
1596
|
const utimesSync = utimes$1.utimesMillisSync;
|
|
1582
1597
|
|
|
@@ -1810,7 +1825,7 @@ var pathExists_1 = {
|
|
|
1810
1825
|
};
|
|
1811
1826
|
|
|
1812
1827
|
const fs$c = gracefulFs;
|
|
1813
|
-
const path$b =
|
|
1828
|
+
const path$b = path__default["default"];
|
|
1814
1829
|
const mkdirp$1 = mkdirs_1.mkdirs;
|
|
1815
1830
|
const pathExists$7 = pathExists_1.pathExists;
|
|
1816
1831
|
const utimes = utimes$1.utimesMillis;
|
|
@@ -2090,7 +2105,7 @@ var copy$1 = {
|
|
|
2090
2105
|
};
|
|
2091
2106
|
|
|
2092
2107
|
const fs$b = gracefulFs;
|
|
2093
|
-
const path$a =
|
|
2108
|
+
const path$a = path__default["default"];
|
|
2094
2109
|
const assert = assert__default["default"];
|
|
2095
2110
|
|
|
2096
2111
|
const isWindows = (process.platform === 'win32');
|
|
@@ -2412,7 +2427,7 @@ var remove$2 = {
|
|
|
2412
2427
|
|
|
2413
2428
|
const u$7 = universalify.fromCallback;
|
|
2414
2429
|
const fs$a = require$$1__default["default"];
|
|
2415
|
-
const path$9 =
|
|
2430
|
+
const path$9 = path__default["default"];
|
|
2416
2431
|
const mkdir$5 = mkdirs_1;
|
|
2417
2432
|
const remove$1 = remove$2;
|
|
2418
2433
|
|
|
@@ -2458,7 +2473,7 @@ var empty = {
|
|
|
2458
2473
|
};
|
|
2459
2474
|
|
|
2460
2475
|
const u$6 = universalify.fromCallback;
|
|
2461
|
-
const path$8 =
|
|
2476
|
+
const path$8 = path__default["default"];
|
|
2462
2477
|
const fs$9 = gracefulFs;
|
|
2463
2478
|
const mkdir$4 = mkdirs_1;
|
|
2464
2479
|
const pathExists$6 = pathExists_1.pathExists;
|
|
@@ -2506,7 +2521,7 @@ var file$1 = {
|
|
|
2506
2521
|
};
|
|
2507
2522
|
|
|
2508
2523
|
const u$5 = universalify.fromCallback;
|
|
2509
|
-
const path$7 =
|
|
2524
|
+
const path$7 = path__default["default"];
|
|
2510
2525
|
const fs$8 = gracefulFs;
|
|
2511
2526
|
const mkdir$3 = mkdirs_1;
|
|
2512
2527
|
const pathExists$5 = pathExists_1.pathExists;
|
|
@@ -2565,7 +2580,7 @@ var link$1 = {
|
|
|
2565
2580
|
createLinkSync
|
|
2566
2581
|
};
|
|
2567
2582
|
|
|
2568
|
-
const path$6 =
|
|
2583
|
+
const path$6 = path__default["default"];
|
|
2569
2584
|
const fs$7 = gracefulFs;
|
|
2570
2585
|
const pathExists$4 = pathExists_1.pathExists;
|
|
2571
2586
|
|
|
@@ -2694,7 +2709,7 @@ var symlinkType_1 = {
|
|
|
2694
2709
|
};
|
|
2695
2710
|
|
|
2696
2711
|
const u$4 = universalify.fromCallback;
|
|
2697
|
-
const path$5 =
|
|
2712
|
+
const path$5 = path__default["default"];
|
|
2698
2713
|
const fs$5 = gracefulFs;
|
|
2699
2714
|
const _mkdirs = mkdirs_1;
|
|
2700
2715
|
const mkdirs = _mkdirs.mkdirs;
|
|
@@ -2923,7 +2938,7 @@ var jsonfile = {
|
|
|
2923
2938
|
writeJsonSync: jsonFile$3.writeFileSync
|
|
2924
2939
|
};
|
|
2925
2940
|
|
|
2926
|
-
const path$4 =
|
|
2941
|
+
const path$4 = path__default["default"];
|
|
2927
2942
|
const mkdir$2 = mkdirs_1;
|
|
2928
2943
|
const pathExists$2 = pathExists_1.pathExists;
|
|
2929
2944
|
const jsonFile$2 = jsonfile;
|
|
@@ -2950,7 +2965,7 @@ function outputJson (file, data, options, callback) {
|
|
|
2950
2965
|
var outputJson_1 = outputJson;
|
|
2951
2966
|
|
|
2952
2967
|
const fs$4 = gracefulFs;
|
|
2953
|
-
const path$3 =
|
|
2968
|
+
const path$3 = path__default["default"];
|
|
2954
2969
|
const mkdir$1 = mkdirs_1;
|
|
2955
2970
|
const jsonFile$1 = jsonfile;
|
|
2956
2971
|
|
|
@@ -2982,7 +2997,7 @@ jsonFile.readJSONSync = jsonFile.readJsonSync;
|
|
|
2982
2997
|
var json = jsonFile;
|
|
2983
2998
|
|
|
2984
2999
|
const fs$3 = gracefulFs;
|
|
2985
|
-
const path$2 =
|
|
3000
|
+
const path$2 = path__default["default"];
|
|
2986
3001
|
const copySync = copySync$1.copySync;
|
|
2987
3002
|
const removeSync = remove$2.removeSync;
|
|
2988
3003
|
const mkdirpSync = mkdirs_1.mkdirsSync;
|
|
@@ -3099,7 +3114,7 @@ var moveSync_1 = {
|
|
|
3099
3114
|
|
|
3100
3115
|
const u$1 = universalify.fromCallback;
|
|
3101
3116
|
const fs$2 = gracefulFs;
|
|
3102
|
-
const path$1 =
|
|
3117
|
+
const path$1 = path__default["default"];
|
|
3103
3118
|
const copy = copy$1.copy;
|
|
3104
3119
|
const remove = remove$2.remove;
|
|
3105
3120
|
const mkdirp = mkdirs_1.mkdirp;
|
|
@@ -3180,7 +3195,7 @@ var move_1 = {
|
|
|
3180
3195
|
|
|
3181
3196
|
const u = universalify.fromCallback;
|
|
3182
3197
|
const fs$1 = gracefulFs;
|
|
3183
|
-
const path =
|
|
3198
|
+
const path = path__default["default"];
|
|
3184
3199
|
const mkdir = mkdirs_1;
|
|
3185
3200
|
const pathExists = pathExists_1.pathExists;
|
|
3186
3201
|
|
|
@@ -3254,7 +3269,7 @@ class Server extends EventEmitter__default["default"] {
|
|
|
3254
3269
|
super();
|
|
3255
3270
|
this.option = option;
|
|
3256
3271
|
this.debug = option("debug");
|
|
3257
|
-
this.file = option("socket",
|
|
3272
|
+
this.file = option("socket", path__default["default"].join(common.cacheDir(), "socket"));
|
|
3258
3273
|
this.server = undefined;
|
|
3259
3274
|
this.option = option;
|
|
3260
3275
|
this._connections = {};
|
|
@@ -3330,16 +3345,40 @@ class Slots extends EventEmitter__default["default"] {
|
|
|
3330
3345
|
this.debug = debug;
|
|
3331
3346
|
this.used = new Map();
|
|
3332
3347
|
this.pending = new Map();
|
|
3348
|
+
this._totalAcquired = 0;
|
|
3333
3349
|
if (this.debug) {
|
|
3334
3350
|
console.log("Slots created", this.toString());
|
|
3335
3351
|
}
|
|
3336
3352
|
}
|
|
3353
|
+
get capacity() {
|
|
3354
|
+
return this.count;
|
|
3355
|
+
}
|
|
3356
|
+
get active() {
|
|
3357
|
+
return this.used.size;
|
|
3358
|
+
}
|
|
3359
|
+
get totalAcquired() {
|
|
3360
|
+
return this._totalAcquired;
|
|
3361
|
+
}
|
|
3362
|
+
tryAcquire(id, data) {
|
|
3363
|
+
if (this.used.size < this.count) {
|
|
3364
|
+
this.used.set(id, data);
|
|
3365
|
+
++this._totalAcquired;
|
|
3366
|
+
if (this.debug) {
|
|
3367
|
+
console.log("tryAcquire succeeded", id, data, this.toString());
|
|
3368
|
+
}
|
|
3369
|
+
this.emit("changed");
|
|
3370
|
+
return true;
|
|
3371
|
+
}
|
|
3372
|
+
return false;
|
|
3373
|
+
}
|
|
3337
3374
|
acquire(id, data, cb) {
|
|
3338
3375
|
if (this.used.size < this.count) {
|
|
3339
3376
|
this.used.set(id, data);
|
|
3377
|
+
++this._totalAcquired;
|
|
3340
3378
|
if (this.debug) {
|
|
3341
3379
|
console.log("acquired slot", id, data, this.toString());
|
|
3342
3380
|
}
|
|
3381
|
+
this.emit("changed");
|
|
3343
3382
|
cb();
|
|
3344
3383
|
}
|
|
3345
3384
|
else {
|
|
@@ -3363,9 +3402,11 @@ class Slots extends EventEmitter__default["default"] {
|
|
|
3363
3402
|
for (const p of this.pending) {
|
|
3364
3403
|
this.used.set(p[0], p[1].data);
|
|
3365
3404
|
this.pending.delete(p[0]);
|
|
3405
|
+
++this._totalAcquired;
|
|
3366
3406
|
p[1].cb();
|
|
3367
3407
|
break;
|
|
3368
3408
|
}
|
|
3409
|
+
this.emit("changed");
|
|
3369
3410
|
}
|
|
3370
3411
|
}
|
|
3371
3412
|
toString() {
|
|
@@ -3385,16 +3426,17 @@ class Slots extends EventEmitter__default["default"] {
|
|
|
3385
3426
|
}
|
|
3386
3427
|
|
|
3387
3428
|
const Version = 5;
|
|
3429
|
+
const ObjectCacheFormatVersion = 2;
|
|
3388
3430
|
function cacheDir(option) {
|
|
3389
3431
|
let dir = option("cache-dir");
|
|
3390
3432
|
if (!dir) {
|
|
3391
|
-
dir =
|
|
3433
|
+
dir = path__default["default"].join(os__default["default"].homedir(), ".cache", "fisk", path__default["default"].basename(option.prefix || ""));
|
|
3392
3434
|
}
|
|
3393
3435
|
return dir;
|
|
3394
3436
|
}
|
|
3395
3437
|
function validateCache(option) {
|
|
3396
3438
|
const dir = cacheDir(option);
|
|
3397
|
-
const file =
|
|
3439
|
+
const file = path__default["default"].join(dir, "version");
|
|
3398
3440
|
// console.log(dir);
|
|
3399
3441
|
let version;
|
|
3400
3442
|
try {
|
|
@@ -3415,11 +3457,36 @@ function validateCache(option) {
|
|
|
3415
3457
|
buf.writeUInt32BE(Version);
|
|
3416
3458
|
fs.writeFileSync(file, buf);
|
|
3417
3459
|
}
|
|
3460
|
+
function validateObjectCache(option) {
|
|
3461
|
+
const dir = cacheDir(option);
|
|
3462
|
+
const objectCacheDir = option.string("object-cache-dir") || path__default["default"].join(dir, "objectcache");
|
|
3463
|
+
const file = path__default["default"].join(objectCacheDir, "version");
|
|
3464
|
+
let version;
|
|
3465
|
+
try {
|
|
3466
|
+
version = fs.readFileSync(file);
|
|
3467
|
+
if (version.readUInt32BE() === ObjectCacheFormatVersion) {
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
catch (err) {
|
|
3472
|
+
/* */
|
|
3473
|
+
}
|
|
3474
|
+
if (version) {
|
|
3475
|
+
console.log(`Wrong object cache version. Destroying object cache ${objectCacheDir}`);
|
|
3476
|
+
}
|
|
3477
|
+
fs.removeSync(objectCacheDir);
|
|
3478
|
+
fs.mkdirpSync(objectCacheDir);
|
|
3479
|
+
const buf = Buffer.allocUnsafe(4);
|
|
3480
|
+
buf.writeUInt32BE(ObjectCacheFormatVersion);
|
|
3481
|
+
fs.writeFileSync(file, buf);
|
|
3482
|
+
}
|
|
3418
3483
|
function common$1(option) {
|
|
3419
3484
|
validateCache(option);
|
|
3485
|
+
validateObjectCache(option);
|
|
3420
3486
|
return {
|
|
3421
3487
|
cacheDir: cacheDir.bind(undefined, option),
|
|
3422
|
-
Version
|
|
3488
|
+
Version,
|
|
3489
|
+
ObjectCacheFormatVersion
|
|
3423
3490
|
};
|
|
3424
3491
|
}
|
|
3425
3492
|
|
|
@@ -3431,10 +3498,10 @@ function requireResolve () {
|
|
|
3431
3498
|
hasRequiredResolve = 1;
|
|
3432
3499
|
|
|
3433
3500
|
// Dependencies
|
|
3434
|
-
var path =
|
|
3501
|
+
var path = path__default["default"];
|
|
3435
3502
|
|
|
3436
3503
|
// Load global paths
|
|
3437
|
-
var globalPaths = require$$1__default$
|
|
3504
|
+
var globalPaths = require$$1__default$1["default"].globalPaths;
|
|
3438
3505
|
|
|
3439
3506
|
// Guess at NPM's global install dir
|
|
3440
3507
|
var npmGlobalPrefix;
|
|
@@ -3524,7 +3591,7 @@ function requireResolve () {
|
|
|
3524
3591
|
}
|
|
3525
3592
|
|
|
3526
3593
|
var appRootPath$1 = function(dirname) {
|
|
3527
|
-
var path =
|
|
3594
|
+
var path = path__default["default"];
|
|
3528
3595
|
var resolve = requireResolve();
|
|
3529
3596
|
var appRootPath = resolve(dirname);
|
|
3530
3597
|
|
|
@@ -3559,7 +3626,7 @@ var xdgBasedir = {};
|
|
|
3559
3626
|
|
|
3560
3627
|
(function (exports) {
|
|
3561
3628
|
const os = os__default["default"];
|
|
3562
|
-
const path =
|
|
3629
|
+
const path = path__default["default"];
|
|
3563
3630
|
|
|
3564
3631
|
const home = os.homedir();
|
|
3565
3632
|
const env = process.env;
|
|
@@ -3931,7 +3998,7 @@ class Engine {
|
|
|
3931
3998
|
_homedir() {
|
|
3932
3999
|
let home = process.env.home;
|
|
3933
4000
|
if (home) {
|
|
3934
|
-
return
|
|
4001
|
+
return path__default["default"].join(home, ".config");
|
|
3935
4002
|
}
|
|
3936
4003
|
return undefined;
|
|
3937
4004
|
}
|
|
@@ -3966,12 +4033,12 @@ class Engine {
|
|
|
3966
4033
|
return 0 /* OptionsReadResult.Failed */;
|
|
3967
4034
|
};
|
|
3968
4035
|
// console.log("about to read file", file, "additionalFiles", this.additionalFiles, "configDirs", this.configDirs, "applicationPath", this.applicationPath, "homedir", this._homedir());
|
|
3969
|
-
if (
|
|
4036
|
+
if (path__default["default"].isAbsolute(file)) {
|
|
3970
4037
|
read(file);
|
|
3971
4038
|
}
|
|
3972
4039
|
else {
|
|
3973
4040
|
this.additionalFiles.forEach(file => {
|
|
3974
|
-
if (
|
|
4041
|
+
if (path__default["default"].isAbsolute(file) && read(file) == 0 /* OptionsReadResult.Failed */) {
|
|
3975
4042
|
read(file + ".conf");
|
|
3976
4043
|
}
|
|
3977
4044
|
});
|
|
@@ -3981,13 +4048,13 @@ class Engine {
|
|
|
3981
4048
|
return;
|
|
3982
4049
|
}
|
|
3983
4050
|
this.additionalFiles.forEach(additional => {
|
|
3984
|
-
if (!
|
|
3985
|
-
let file =
|
|
4051
|
+
if (!path__default["default"].isAbsolute(additional)) {
|
|
4052
|
+
let file = path__default["default"].join(root, additional);
|
|
3986
4053
|
if (read(file) == 0 /* OptionsReadResult.Failed */)
|
|
3987
4054
|
read(file + ".conf");
|
|
3988
4055
|
}
|
|
3989
4056
|
});
|
|
3990
|
-
let filePath =
|
|
4057
|
+
let filePath = path__default["default"].join(root, file);
|
|
3991
4058
|
if (read(filePath) == 0 /* OptionsReadResult.Failed */) {
|
|
3992
4059
|
read(filePath + ".conf");
|
|
3993
4060
|
}
|
|
@@ -4084,6 +4151,22 @@ function createOptions (optionsOptions, argv) {
|
|
|
4084
4151
|
});
|
|
4085
4152
|
}
|
|
4086
4153
|
|
|
4154
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
4155
|
+
console.log(`Usage: fisk-daemon [options]
|
|
4156
|
+
|
|
4157
|
+
Options:
|
|
4158
|
+
--debug Enable debug logging
|
|
4159
|
+
--socket=PATH Unix socket path (default: ~/.cache/fisk/daemon/socket)
|
|
4160
|
+
--cpp-slots=N Preprocess slot count (default: cpus * 2)
|
|
4161
|
+
--slots=N Compile slot count (default: cpus)
|
|
4162
|
+
--local-slots=N Local compile slot count (default: 0, disabled)
|
|
4163
|
+
--local-slots-max-load=N Max system load average (1-min) to allow local compiles (default: 0, no limit)
|
|
4164
|
+
--cache-dir=PATH Cache directory (default: ~/.cache/fisk/daemon)
|
|
4165
|
+
|
|
4166
|
+
Config files: ~/.config/fisk/daemon.conf, /etc/xdg/fisk/daemon.conf
|
|
4167
|
+
Environment variables: FISK_DAEMON_DEBUG, FISK_DAEMON_SLOTS, etc.`);
|
|
4168
|
+
process.exit(0);
|
|
4169
|
+
}
|
|
4087
4170
|
const option = createOptions({
|
|
4088
4171
|
prefix: "fisk/daemon",
|
|
4089
4172
|
noApplicationPath: true,
|
|
@@ -4113,15 +4196,87 @@ server.on("error", (err) => {
|
|
|
4113
4196
|
});
|
|
4114
4197
|
const cppSlots = new Slots(option.int("cpp-slots", Math.max(os__default["default"].cpus().length * 2, 1)), "cpp", debug);
|
|
4115
4198
|
const compileSlots = new Slots(option.int("slots", Math.max(os__default["default"].cpus().length, 1)), "compile", debug);
|
|
4199
|
+
const localSlotCount = option.int("local-slots", 0);
|
|
4200
|
+
const localSlots = new Slots(localSlotCount, "local", debug);
|
|
4201
|
+
const localSlotsMaxLoad = option("local-slots-max-load") || 0;
|
|
4202
|
+
const slotSubscribers = [];
|
|
4203
|
+
function slotsInfo() {
|
|
4204
|
+
return {
|
|
4205
|
+
type: "slotsInfo",
|
|
4206
|
+
local: {
|
|
4207
|
+
active: localSlots.active,
|
|
4208
|
+
capacity: localSlots.capacity,
|
|
4209
|
+
total: localSlots.totalAcquired
|
|
4210
|
+
},
|
|
4211
|
+
cpp: {
|
|
4212
|
+
active: cppSlots.active,
|
|
4213
|
+
capacity: cppSlots.capacity,
|
|
4214
|
+
total: cppSlots.totalAcquired
|
|
4215
|
+
},
|
|
4216
|
+
compile: {
|
|
4217
|
+
active: compileSlots.active,
|
|
4218
|
+
capacity: compileSlots.capacity,
|
|
4219
|
+
total: compileSlots.totalAcquired
|
|
4220
|
+
}
|
|
4221
|
+
};
|
|
4222
|
+
}
|
|
4223
|
+
function broadcastSlotsInfo() {
|
|
4224
|
+
if (slotSubscribers.length === 0) {
|
|
4225
|
+
return;
|
|
4226
|
+
}
|
|
4227
|
+
const info = slotsInfo();
|
|
4228
|
+
for (const sub of slotSubscribers) {
|
|
4229
|
+
sub.compile.send(info);
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
for (const slots of [localSlots, cppSlots, compileSlots]) {
|
|
4233
|
+
slots.on("changed", broadcastSlotsInfo);
|
|
4234
|
+
}
|
|
4235
|
+
function canAcquireLocalSlot() {
|
|
4236
|
+
if (localSlotCount <= 0) {
|
|
4237
|
+
return false;
|
|
4238
|
+
}
|
|
4239
|
+
if (localSlotsMaxLoad > 0) {
|
|
4240
|
+
const loadAvg = os__default["default"].loadavg()[0];
|
|
4241
|
+
if (loadAvg > localSlotsMaxLoad) {
|
|
4242
|
+
if (debug) {
|
|
4243
|
+
console.log(`Local slot denied: load ${loadAvg.toFixed(2)} > max ${localSlotsMaxLoad}`);
|
|
4244
|
+
}
|
|
4245
|
+
return false;
|
|
4246
|
+
}
|
|
4247
|
+
}
|
|
4248
|
+
return true;
|
|
4249
|
+
}
|
|
4116
4250
|
server.on("compile", (compile) => {
|
|
4117
4251
|
compile.on("dumpSlots", () => {
|
|
4118
|
-
const ret = { cpp: cppSlots.dump(), compile: compileSlots.dump() };
|
|
4252
|
+
const ret = { cpp: cppSlots.dump(), compile: compileSlots.dump(), local: localSlots.dump() };
|
|
4119
4253
|
if (debug) {
|
|
4120
4254
|
console.log("sending dump", ret);
|
|
4121
4255
|
}
|
|
4122
4256
|
compile.send(ret);
|
|
4123
4257
|
});
|
|
4258
|
+
compile.on("subscribeSlots", () => {
|
|
4259
|
+
if (debug) {
|
|
4260
|
+
console.log("subscribeSlots from", compile.id);
|
|
4261
|
+
}
|
|
4262
|
+
const subscriber = {
|
|
4263
|
+
compile,
|
|
4264
|
+
handler: () => {
|
|
4265
|
+
// Remove subscriber on disconnect
|
|
4266
|
+
const idx = slotSubscribers.indexOf(subscriber);
|
|
4267
|
+
if (idx !== -1) {
|
|
4268
|
+
slotSubscribers.splice(idx, 1);
|
|
4269
|
+
}
|
|
4270
|
+
}
|
|
4271
|
+
};
|
|
4272
|
+
slotSubscribers.push(subscriber);
|
|
4273
|
+
compile.on("end", subscriber.handler);
|
|
4274
|
+
compile.on("error", subscriber.handler);
|
|
4275
|
+
// Send current state immediately
|
|
4276
|
+
compile.send(slotsInfo());
|
|
4277
|
+
});
|
|
4124
4278
|
let requestedCppSlot = false;
|
|
4279
|
+
let requestedLocalSlot = false;
|
|
4125
4280
|
compile.on("acquireCppSlot", () => {
|
|
4126
4281
|
if (debug) {
|
|
4127
4282
|
console.log("acquireCppSlot");
|
|
@@ -4165,6 +4320,38 @@ server.on("compile", (compile) => {
|
|
|
4165
4320
|
compileSlots.release(compile.id);
|
|
4166
4321
|
}
|
|
4167
4322
|
});
|
|
4323
|
+
compile.on("acquireSlot", () => {
|
|
4324
|
+
if (debug) {
|
|
4325
|
+
console.log("acquireSlot");
|
|
4326
|
+
}
|
|
4327
|
+
if (canAcquireLocalSlot() && localSlots.tryAcquire(compile.id, { pid: compile.pid })) {
|
|
4328
|
+
if (debug) {
|
|
4329
|
+
console.log("acquireSlot -> local slot granted");
|
|
4330
|
+
}
|
|
4331
|
+
requestedLocalSlot = true;
|
|
4332
|
+
compile.send(Constants.LocalSlotAcquired);
|
|
4333
|
+
}
|
|
4334
|
+
else {
|
|
4335
|
+
if (debug) {
|
|
4336
|
+
console.log("acquireSlot -> falling back to cpp slot");
|
|
4337
|
+
}
|
|
4338
|
+
assert__default["default"](!requestedCppSlot);
|
|
4339
|
+
requestedCppSlot = true;
|
|
4340
|
+
cppSlots.acquire(compile.id, { pid: compile.pid }, () => {
|
|
4341
|
+
compile.send(Constants.CppSlotAcquired);
|
|
4342
|
+
});
|
|
4343
|
+
}
|
|
4344
|
+
});
|
|
4345
|
+
compile.on("releaseLocalSlot", () => {
|
|
4346
|
+
if (debug) {
|
|
4347
|
+
console.log("releaseLocalSlot");
|
|
4348
|
+
}
|
|
4349
|
+
assert__default["default"](requestedLocalSlot);
|
|
4350
|
+
if (requestedLocalSlot) {
|
|
4351
|
+
requestedLocalSlot = false;
|
|
4352
|
+
localSlots.release(compile.id);
|
|
4353
|
+
}
|
|
4354
|
+
});
|
|
4168
4355
|
compile.on("error", (err) => {
|
|
4169
4356
|
if (debug) {
|
|
4170
4357
|
console.error("Got error from fiskc", compile.id, compile.pid, err);
|
|
@@ -4177,6 +4364,10 @@ server.on("compile", (compile) => {
|
|
|
4177
4364
|
requestedCompileSlot = false;
|
|
4178
4365
|
compileSlots.release(compile.id);
|
|
4179
4366
|
}
|
|
4367
|
+
if (requestedLocalSlot) {
|
|
4368
|
+
requestedLocalSlot = false;
|
|
4369
|
+
localSlots.release(compile.id);
|
|
4370
|
+
}
|
|
4180
4371
|
});
|
|
4181
4372
|
compile.on("end", () => {
|
|
4182
4373
|
if (debug) {
|
|
@@ -4190,6 +4381,10 @@ server.on("compile", (compile) => {
|
|
|
4190
4381
|
requestedCompileSlot = false;
|
|
4191
4382
|
compileSlots.release(compile.id);
|
|
4192
4383
|
}
|
|
4384
|
+
if (requestedLocalSlot) {
|
|
4385
|
+
requestedLocalSlot = false;
|
|
4386
|
+
localSlots.release(compile.id);
|
|
4387
|
+
}
|
|
4193
4388
|
});
|
|
4194
4389
|
});
|
|
4195
4390
|
process.on("exit", () => {
|