fix(nix-monitor): change to file-based approach

The previous implementation has a bug when terminating noctalia's runStream function. Somehow, it doesn't want to spawn again after sometimes. This commit change the implementation to use a temporary file and read the command's output from there
This commit is contained in:
avivbintangaringga
2026-07-14 21:03:49 +07:00
parent 465cbb2456
commit 46e6b4b25e
+87 -37
View File
@@ -1,4 +1,4 @@
noctalia.setUpdateInterval(100) noctalia.setUpdateInterval(1000)
function tr(key) function tr(key)
return noctalia.tr(key) return noctalia.tr(key)
@@ -24,17 +24,21 @@ local branch = cfg("branch")
local updateCheckInterval = cfg("check_interval") local updateCheckInterval = cfg("check_interval")
local checkDurationThreshold = cfg("check_duration_threshold") local checkDurationThreshold = cfg("check_duration_threshold")
local systemStatsCheckInterval = cfg("system_stats_check_interval") local systemStatsCheckInterval = cfg("system_stats_check_interval")
local completedCommands = 0
local isInit = true local isInit = true
local stateDir = "/tmp/nix-monitor"
local localHashFile = stateDir .. "/localHash"
local remoteHashFile = stateDir .. "/remoteHash"
local storeSizeFile = stateDir .. "/storeSize"
local closureSizeFile = stateDir .. "/closureSize"
local localHashCmd = "nixos-version --hash 2> /dev/null | cut -c -7" local localHashCmd = "nixos-version --hash 2> /dev/null | cut -c -7 > " .. localHashFile .. " &"
local remoteHashCmd = "sleep 5 && git ls-remote https://github.com/NixOS/nixpkgs " .. branch .. " 2>/dev/null | cut -c 1-7" local remoteHashCmd = "sleep 5 && git ls-remote https://github.com/NixOS/nixpkgs " .. branch .. " 2>/dev/null | cut -c 1-7 > " .. remoteHashFile .. " &"
local nixosGenerationsCmd = "nixos-rebuild list-generations | tail -n +2 | wc -l" local nixosGenerationsCmd = "nixos-rebuild list-generations | tail -n +2 | wc -l"
local nixosCurrentGenCmd = "nixos-rebuild list-generations | grep True | awk '{print $1}'" local nixosCurrentGenCmd = "nixos-rebuild list-generations | grep True | awk '{print $1}'"
local hmGenerationsCmd = "home-manager generations | wc -l" local hmGenerationsCmd = "home-manager generations | wc -l"
local hmCurrentGenCmd = "home-manager generations | grep '(current)' | awk '{print $5}'" local hmCurrentGenCmd = "home-manager generations | grep '(current)' | awk '{print $5}'"
local storeSizeCmd = `du -s --block-size=1GiB /nix/store | awk '\{print $1 " GiB"\}'` local storeSizeCmd = `du -s --block-size=1GiB /nix/store | awk '\{print $1 " GiB"\}' > {storeSizeFile} &`
local closureSizeCmd = "nix path-info --closure-size --human-readable /run/current-system | awk '{print $2, $3}'" local closureSizeCmd = `nix path-info --closure-size --human-readable /run/current-system | awk '\{print $2, $3\}' > {closureSizeFile} &`
setState("lastRunTime", os.time()) setState("lastRunTime", os.time())
setState("lastCheckTime", os.time()) setState("lastCheckTime", os.time())
@@ -43,6 +47,7 @@ setState("localHash", "n/a")
setState("remoteHash", "n/a") setState("remoteHash", "n/a")
setState("isRunning", false) setState("isRunning", false)
setState("isUpdateAvailable", false) setState("isUpdateAvailable", false)
setState("lastGenerationsCheckTime", 0)
setState("lastSystemStatsCheckTime", 0) setState("lastSystemStatsCheckTime", 0)
setState("hasHomeManager", noctalia.commandExists("home-manager")) setState("hasHomeManager", noctalia.commandExists("home-manager"))
setState("nixosGenerations", "•••") setState("nixosGenerations", "•••")
@@ -52,16 +57,35 @@ setState("hmCurrentGen", "•••")
setState("storeSize", "•••") setState("storeSize", "•••")
setState("closureSize", "•••") setState("closureSize", "•••")
noctalia.mkdirAll(stateDir)
noctalia.writeFile(localHashFile, "")
noctalia.writeFile(remoteHashFile, "")
function update() function update()
if isInit or (os.time() - getState("lastCheckTime")) >= 60 * updateCheckInterval then if isInit or (os.time() - getState("lastCheckTime")) >= 60 * updateCheckInterval then
isInit = false isInit = false
cancelCheck()
checkUpdate() checkUpdate()
end end
if getState("isRunning") then
if isCheckUpdateSuccessfully() then
onHashCheckCompleted()
end
end
if getState("isSystemStatsCheckRunning") then
checkSystemStatsFile()
end
if getState("isRunning") and (os.time() - getState("lastRunTime")) >= 60 * checkDurationThreshold then if getState("isRunning") and (os.time() - getState("lastRunTime")) >= 60 * checkDurationThreshold then
cancelCheck() cancelCheck()
end end
if (os.time() - getState("lastGenerationsCheckTime")) >= 20 then
checkGenerations()
end
if (os.time() - getState("lastSystemStatsCheckTime")) >= 60 * systemStatsCheckInterval then if (os.time() - getState("lastSystemStatsCheckTime")) >= 60 * systemStatsCheckInterval then
checkSystemStats() checkSystemStats()
end end
@@ -80,37 +104,36 @@ function checkUpdate()
setState("isRunning", true) setState("isRunning", true)
completedCommands = 0 noctalia.writeFile(localHashFile, "")
noctalia.writeFile(remoteHashFile, "")
noctalia.runAsync(localHashCmd, getLocalHash) noctalia.runAsync(localHashCmd)
noctalia.runStream(remoteHashCmd, getRemoteHash) noctalia.runAsync(remoteHashCmd)
end end
function getLocalHash(result) function isCheckUpdateSuccessfully()
if getState("isRunning") ~= true then local localHash = noctalia.string.trim(noctalia.readFile(localHashFile))
return local remoteHash = noctalia.string.trim(noctalia.readFile(remoteHashFile))
if typeof(localHash) == "string" and localHash ~= "" then
setState("localHash", localHash)
end end
setState("localHash", result.stdout) if typeof(remoteHash) == "string" and remoteHash ~= "" then
completedCommands += 1 setState("remoteHash", remoteHash)
onHashCheckCompleted()
end
function getRemoteHash(line)
if getState("isRunning") ~= true then
return
end end
setState("remoteHash", line) local success = typeof(localHash) == "string" and localHash ~= "" and
completedCommands += 1 typeof(remoteHash) == "string" and remoteHash ~= ""
onHashCheckCompleted()
if success then
onHashCheckCompleted()
end
return success
end end
function onHashCheckCompleted() function onHashCheckCompleted()
if completedCommands < 2 then
return
end
if getState("localHash") ~= getState("remoteHash") then if getState("localHash") ~= getState("remoteHash") then
setState("isUpdateAvailable", true) setState("isUpdateAvailable", true)
if cfg("show_update_notification") then if cfg("show_update_notification") then
@@ -129,9 +152,8 @@ function onHashCheckCompleted()
end end
function cancelCheck() function cancelCheck()
noctalia.runAsync(`kill $(ps -ef | grep "git ls-remote https://github.com/NixOS/nixpkgs" | grep -v grep | awk '\{print $2\}')`)
setState("isRunning", false) setState("isRunning", false)
completedCommands = 0 noctalia.runAsync(`kill $(ps -ef | grep "git ls-remote https://github.com/NixOS/nixpkgs" | grep -v grep | awk '\{print $2\}')`)
end end
watchState("command", function(command) watchState("command", function(command)
@@ -144,8 +166,8 @@ watchState("command", function(command)
end end
end) end)
function checkSystemStats() function checkGenerations()
setState("lastSystemStatsCheckTime", os.time()) setState("lastGenerationsCheckTime", os.time())
noctalia.runAsync(nixosGenerationsCmd, function(result) noctalia.runAsync(nixosGenerationsCmd, function(result)
setState("nixosGenerations", result.stdout) setState("nixosGenerations", result.stdout)
@@ -164,12 +186,40 @@ function checkSystemStats()
setState("hmCurrentGen", result.stdout) setState("hmCurrentGen", result.stdout)
end) end)
end end
end
noctalia.runStream(storeSizeCmd, function(line) function checkSystemStats()
setState("storeSize", line) if getState("isSystemStatsCheckRunning") then
end) return
end
noctalia.runStream(closureSizeCmd, function(line) setState("isSystemStatsCheckRunning", true)
setState("closureSize", line) setState("lastSystemStatsCheckTime", os.time())
end)
noctalia.runAsync(storeSizeCmd)
noctalia.runAsync(closureSizeCmd)
end
function checkSystemStatsFile()
local storeSize = noctalia.string.trim(noctalia.readFile(storeSizeFile))
local closureSize = noctalia.string.trim(noctalia.readFile(closureSizeFile))
if typeof(storeSize) == "string" and storeSize ~= "" then
setState("storeSize", storeSize)
end
if typeof(closureSize) == "string" and closureSize ~= "" then
setState("closureSize", closureSize)
end
local success = typeof(storeSize) == "string" and storeSize ~= "" and
typeof(closureSize) == "string" and closureSize ~= ""
if success then
setState("isSystemStatsCheckRunning", false)
end
end
function onExit(signal)
cancelCheck()
end end