From d9282b16cb5ec6a275acde30b76d259385f3d7aa Mon Sep 17 00:00:00 2001 From: Cameron Aaron Date: Tue, 12 Nov 2024 17:16:50 -0800 Subject: [PATCH] Switch to pmset Fixes #512 --- .../services/caffeinateService/index.ts | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/server/src/server/services/caffeinateService/index.ts b/packages/server/src/server/services/caffeinateService/index.ts index 5a3495d4..bd7d520d 100644 --- a/packages/server/src/server/services/caffeinateService/index.ts +++ b/packages/server/src/server/services/caffeinateService/index.ts @@ -3,7 +3,7 @@ import { spawn, ChildProcessWithoutNullStreams } from "child_process"; import { Loggable } from "@server/lib/logging/Loggable"; /** - * Service that spawns the caffeinate process so that + * Service that spawns the pmset process so that * the macOS operating system does not sleep until the server * exits. */ @@ -14,20 +14,26 @@ export class CaffeinateService extends Loggable { childProc: ChildProcessWithoutNullStreams; + originalSleepSettings: { displaysleep: string; disksleep: string; sleep: string } = { + displaysleep: "", + disksleep: "", + sleep: "" + }; + /** - * Runs caffeinate until the current process is killed + * Runs pmset until the current process is killed */ start() { if (this.isCaffeinated) return; const myPid = process.pid; + // Cache existing sleep values + this.cacheSleepValues(); + // Spawn the child process - // -i: Create an assertion to prevent the system from idle sleeping. - // -m: Create an assertion to prevent the disk from idle sleeping. - // -s: Create an assertion to prevent the system from sleeping - // -w: Waits for the process with the specified pid to exit. - this.childProc = spawn("caffeinate", ["-i", "-m", "-s", "-w", myPid.toString()], { detached: true }); - this.log.info(`Spawned Caffeinate with PID: ${this.childProc.pid}`); + // Prevent system sleep + this.childProc = spawn("pmset", ["-a", "displaysleep", "0", "disksleep", "0", "sleep", "0"], { detached: true }); + this.log.info(`Spawned pmset with PID: ${this.childProc.pid}`); this.isCaffeinated = true; // Setup listeners @@ -47,21 +53,54 @@ export class CaffeinateService extends Loggable { try { const killed = this.childProc.kill(); if (!killed) process.kill(-this.childProc.pid); - this.log.debug("Killed caffeinate process"); + this.log.debug("Killed pmset process"); } catch (ex: any) { - this.log.error(`Failed to kill caffeinate process! ${ex.message}`); + this.log.error(`Failed to kill pmset process! ${ex.message}`); } finally { this.isCaffeinated = false; + // Restore cached sleep values + this.restoreSleepValues(); } } } /** - * Method to let us know that the caffeinate process has ended + * Method to let us know that the pmset process has ended * * @param _ The message returned by the EventEmitter */ private onClose(msg: any) { this.isCaffeinated = false; } + + /** + * Cache the current sleep values + */ + private cacheSleepValues() { + const displaysleep = this.executePmsetCommand("displaysleep"); + const disksleep = this.executePmsetCommand("disksleep"); + const sleep = this.executePmsetCommand("sleep"); + + this.originalSleepSettings = { displaysleep, disksleep, sleep }; + } + + /** + * Restore the cached sleep values + */ + private restoreSleepValues() { + const { displaysleep, disksleep, sleep } = this.originalSleepSettings; + + this.executePmsetCommand("displaysleep", displaysleep); + this.executePmsetCommand("disksleep", disksleep); + this.executePmsetCommand("sleep", sleep); + } + + /** + * Execute pmset command + */ + private executePmsetCommand(setting: string, value?: string): string { + const args = value ? ["-a", setting, value] : ["-g", setting]; + const result = spawnSync("pmset", args); + return result.stdout.toString().trim(); + } }