@andersbakken/fisk 4.0.56 → 4.0.57

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.
@@ -3345,16 +3345,28 @@ class Slots extends EventEmitter__default["default"] {
3345
3345
  this.debug = debug;
3346
3346
  this.used = new Map();
3347
3347
  this.pending = new Map();
3348
+ this._totalAcquired = 0;
3348
3349
  if (this.debug) {
3349
3350
  console.log("Slots created", this.toString());
3350
3351
  }
3351
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
+ }
3352
3362
  tryAcquire(id, data) {
3353
3363
  if (this.used.size < this.count) {
3354
3364
  this.used.set(id, data);
3365
+ ++this._totalAcquired;
3355
3366
  if (this.debug) {
3356
3367
  console.log("tryAcquire succeeded", id, data, this.toString());
3357
3368
  }
3369
+ this.emit("changed");
3358
3370
  return true;
3359
3371
  }
3360
3372
  return false;
@@ -3362,9 +3374,11 @@ class Slots extends EventEmitter__default["default"] {
3362
3374
  acquire(id, data, cb) {
3363
3375
  if (this.used.size < this.count) {
3364
3376
  this.used.set(id, data);
3377
+ ++this._totalAcquired;
3365
3378
  if (this.debug) {
3366
3379
  console.log("acquired slot", id, data, this.toString());
3367
3380
  }
3381
+ this.emit("changed");
3368
3382
  cb();
3369
3383
  }
3370
3384
  else {
@@ -3388,9 +3402,11 @@ class Slots extends EventEmitter__default["default"] {
3388
3402
  for (const p of this.pending) {
3389
3403
  this.used.set(p[0], p[1].data);
3390
3404
  this.pending.delete(p[0]);
3405
+ ++this._totalAcquired;
3391
3406
  p[1].cb();
3392
3407
  break;
3393
3408
  }
3409
+ this.emit("changed");
3394
3410
  }
3395
3411
  }
3396
3412
  toString() {
@@ -4183,6 +4199,39 @@ const compileSlots = new Slots(option.int("slots", Math.max(os__default["default
4183
4199
  const localSlotCount = option.int("local-slots", 0);
4184
4200
  const localSlots = new Slots(localSlotCount, "local", debug);
4185
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
+ }
4186
4235
  function canAcquireLocalSlot() {
4187
4236
  if (localSlotCount <= 0) {
4188
4237
  return false;
@@ -4206,6 +4255,26 @@ server.on("compile", (compile) => {
4206
4255
  }
4207
4256
  compile.send(ret);
4208
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
+ });
4209
4278
  let requestedCppSlot = false;
4210
4279
  let requestedLocalSlot = false;
4211
4280
  compile.on("acquireCppSlot", () => {
@@ -5895,6 +5895,7 @@ if (process.argv.includes("--help") || process.argv.includes("-h")) {
5895
5895
 
5896
5896
  Options:
5897
5897
  --scheduler=URL Scheduler URL (default: ws://localhost:8097)
5898
+ --daemon-socket=PATH Daemon Unix socket path (default: ~/.cache/fisk/daemon/socket)
5898
5899
 
5899
5900
  Config files: ~/.config/fisk/monitor.conf, /etc/xdg/fisk/monitor.conf
5900
5901
  Environment variables: FISK_MONITOR_SCHEDULER, etc.`);
@@ -6298,7 +6299,13 @@ function notify(msg) {
6298
6299
  return;
6299
6300
  }
6300
6301
  const notifyNow = (message) => {
6301
- notificationBox.setContent(message || "");
6302
+ if (message) {
6303
+ notificationBox.setContent(message);
6304
+ }
6305
+ else {
6306
+ updateNotificationBar();
6307
+ return;
6308
+ }
6302
6309
  screen.render();
6303
6310
  };
6304
6311
  notificationInterval = setInterval(() => {
@@ -6624,5 +6631,91 @@ function connect() {
6624
6631
  setTimeout(connect, 1000);
6625
6632
  });
6626
6633
  }
6634
+ // --- Daemon connection for local slot info ---
6635
+ const DaemonJSON = 5;
6636
+ const DaemonJSONResponse = 12;
6637
+ const daemonSocketPath = String(option("daemon-socket", path__default["default"].join(require$$2__default["default"].homedir(), ".cache", "fisk", "daemon", "socket")));
6638
+ let daemonSlotsInfo;
6639
+ let daemonSocket;
6640
+ let daemonRecvBuffer = Buffer.alloc(0);
6641
+ function updateNotificationBar() {
6642
+ if (daemonSlotsInfo && daemonSlotsInfo.local.capacity > 0) {
6643
+ const local = daemonSlotsInfo.local;
6644
+ notificationBox.setContent(`{bold}Local:{/bold} ${local.active}/${local.capacity} active, ${local.total} total`);
6645
+ }
6646
+ else {
6647
+ notificationBox.setContent("");
6648
+ }
6649
+ screen.render();
6650
+ }
6651
+ function processDaemonMessage(json) {
6652
+ try {
6653
+ const msg = JSON.parse(json);
6654
+ if (msg.type === "slotsInfo") {
6655
+ daemonSlotsInfo = msg;
6656
+ updateNotificationBar();
6657
+ }
6658
+ }
6659
+ catch (e) {
6660
+ // ignore parse errors
6661
+ }
6662
+ }
6663
+ function processDaemonData() {
6664
+ while (daemonRecvBuffer.length > 0) {
6665
+ const type = daemonRecvBuffer[0];
6666
+ if (type === DaemonJSONResponse) {
6667
+ if (daemonRecvBuffer.length < 5) {
6668
+ break; // need more data for length header
6669
+ }
6670
+ const msgLen = daemonRecvBuffer.readUInt32BE(1);
6671
+ if (daemonRecvBuffer.length < 5 + msgLen) {
6672
+ break; // need more data for body
6673
+ }
6674
+ const json = daemonRecvBuffer.subarray(5, 5 + msgLen).toString("utf8");
6675
+ daemonRecvBuffer = daemonRecvBuffer.subarray(5 + msgLen);
6676
+ processDaemonMessage(json);
6677
+ }
6678
+ else {
6679
+ // Unknown single-byte message, skip it
6680
+ daemonRecvBuffer = daemonRecvBuffer.subarray(1);
6681
+ }
6682
+ }
6683
+ }
6684
+ function sendDaemonJSON(sock, obj) {
6685
+ const jsonBuf = Buffer.from(JSON.stringify(obj), "utf8");
6686
+ const header = Buffer.allocUnsafe(5);
6687
+ header.writeUInt8(DaemonJSON, 0);
6688
+ header.writeUInt32BE(jsonBuf.length, 1);
6689
+ sock.write(header);
6690
+ sock.write(jsonBuf);
6691
+ }
6692
+ function connectDaemon() {
6693
+ daemonSlotsInfo = undefined;
6694
+ daemonRecvBuffer = Buffer.alloc(0);
6695
+ daemonSocket = require$$3__default["default"].createConnection(daemonSocketPath);
6696
+ daemonSocket.on("connect", () => {
6697
+ assert__default["default"](daemonSocket);
6698
+ // Send PID (4 bytes, big-endian) as the daemon protocol requires
6699
+ const pidBuf = Buffer.allocUnsafe(4);
6700
+ pidBuf.writeUInt32BE(process.pid, 0);
6701
+ daemonSocket.write(pidBuf);
6702
+ // Subscribe to slot updates
6703
+ sendDaemonJSON(daemonSocket, { type: "subscribeSlots" });
6704
+ });
6705
+ daemonSocket.on("data", (data) => {
6706
+ daemonRecvBuffer = Buffer.concat([daemonRecvBuffer, data]);
6707
+ processDaemonData();
6708
+ });
6709
+ daemonSocket.on("error", () => {
6710
+ // Daemon may not be running, silently retry
6711
+ });
6712
+ daemonSocket.on("close", () => {
6713
+ daemonSocket = undefined;
6714
+ daemonSlotsInfo = undefined;
6715
+ updateNotificationBar();
6716
+ setTimeout(connectDaemon, 5000);
6717
+ });
6718
+ }
6627
6719
  connect();
6720
+ connectDaemon();
6628
6721
  //# sourceMappingURL=fisk-monitor.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andersbakken/fisk",
3
- "version": "4.0.56",
3
+ "version": "4.0.57",
4
4
  "description": "Fisk, a distributed compile system",
5
5
  "scripts": {
6
6
  "lint": "eslint . --ext .ts",