mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-13 00:42:49 -05:00
proc: timeout to CLI helper
This commit is contained in:
@@ -9,20 +9,23 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property int defaultDebounceMs: 50
|
property int defaultDebounceMs: 50
|
||||||
|
property int defaultTimeoutMs: 10000
|
||||||
property var _procDebouncers: ({}) // id -> { timer, command, callback, waitMs }
|
property var _procDebouncers: ({}) // id -> { timer, command, callback, waitMs }
|
||||||
|
|
||||||
function runCommand(id, command, callback, debounceMs) {
|
function runCommand(id, command, callback, debounceMs, timeoutMs) {
|
||||||
const wait = (typeof debounceMs === "number" && debounceMs >= 0) ? debounceMs : defaultDebounceMs
|
const wait = (typeof debounceMs === "number" && debounceMs >= 0) ? debounceMs : defaultDebounceMs
|
||||||
let procId = id ? id : Math.random()
|
const timeout = (typeof timeoutMs === "number" && timeoutMs > 0) ? timeoutMs : defaultTimeoutMs
|
||||||
|
let procId = id ? id : Math.random()
|
||||||
|
|
||||||
if (!_procDebouncers[procId]) {
|
if (!_procDebouncers[procId]) {
|
||||||
const t = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
|
const t = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
|
||||||
t.triggered.connect(function() { _launchProc(procId) })
|
t.triggered.connect(function() { _launchProc(procId) })
|
||||||
_procDebouncers[procId] = { timer: t, command: command, callback: callback, waitMs: wait }
|
_procDebouncers[procId] = { timer: t, command: command, callback: callback, waitMs: wait, timeoutMs: timeout }
|
||||||
} else {
|
} else {
|
||||||
_procDebouncers[procId].command = command
|
_procDebouncers[procId].command = command
|
||||||
_procDebouncers[procId].callback = callback
|
_procDebouncers[procId].callback = callback
|
||||||
_procDebouncers[procId].waitMs = wait
|
_procDebouncers[procId].waitMs = wait
|
||||||
|
_procDebouncers[procId].timeoutMs = timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
const entry = _procDebouncers[procId]
|
const entry = _procDebouncers[procId]
|
||||||
@@ -37,34 +40,61 @@ Singleton {
|
|||||||
const proc = Qt.createQmlObject('import Quickshell.Io; Process { running: false }', root)
|
const proc = Qt.createQmlObject('import Quickshell.Io; Process { running: false }', root)
|
||||||
const out = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
const out = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
||||||
const err = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
const err = Qt.createQmlObject('import Quickshell.Io; StdioCollector {}', proc)
|
||||||
|
const timeoutTimer = Qt.createQmlObject('import QtQuick; Timer { repeat: false }', root)
|
||||||
|
|
||||||
proc.stdout = out
|
proc.stdout = out
|
||||||
proc.stderr = err
|
proc.stderr = err
|
||||||
proc.command = entry.command
|
proc.command = entry.command
|
||||||
|
|
||||||
let capturedOut = ""
|
let capturedOut = ""
|
||||||
|
let capturedErr = ""
|
||||||
let exitSeen = false
|
let exitSeen = false
|
||||||
let exitCodeValue = -1
|
let exitCodeValue = -1
|
||||||
|
let outSeen = false
|
||||||
|
let errSeen = false
|
||||||
|
let timedOut = false
|
||||||
|
|
||||||
|
timeoutTimer.interval = entry.timeoutMs
|
||||||
|
timeoutTimer.triggered.connect(function() {
|
||||||
|
if (!exitSeen) {
|
||||||
|
timedOut = true
|
||||||
|
proc.running = false
|
||||||
|
exitSeen = true
|
||||||
|
exitCodeValue = 124
|
||||||
|
maybeComplete()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
out.streamFinished.connect(function() {
|
out.streamFinished.connect(function() {
|
||||||
capturedOut = out.text || ""
|
capturedOut = out.text || ""
|
||||||
|
outSeen = true
|
||||||
|
maybeComplete()
|
||||||
|
})
|
||||||
|
|
||||||
|
err.streamFinished.connect(function() {
|
||||||
|
capturedErr = err.text || ""
|
||||||
|
errSeen = true
|
||||||
maybeComplete()
|
maybeComplete()
|
||||||
})
|
})
|
||||||
|
|
||||||
proc.exited.connect(function(code) {
|
proc.exited.connect(function(code) {
|
||||||
|
timeoutTimer.stop()
|
||||||
exitSeen = true
|
exitSeen = true
|
||||||
exitCodeValue = code
|
exitCodeValue = code
|
||||||
maybeComplete()
|
maybeComplete()
|
||||||
})
|
})
|
||||||
|
|
||||||
function maybeComplete() {
|
function maybeComplete() {
|
||||||
if (!exitSeen) return
|
if (!exitSeen || !outSeen || !errSeen) return
|
||||||
|
timeoutTimer.stop()
|
||||||
if (typeof entry.callback === "function") {
|
if (typeof entry.callback === "function") {
|
||||||
try { entry.callback(capturedOut, exitCodeValue) } catch (e) { console.warn("runCommand callback error:", e) }
|
try { entry.callback(capturedOut, exitCodeValue) } catch (e) { console.warn("runCommand callback error:", e) }
|
||||||
}
|
}
|
||||||
try { proc.destroy() } catch (_) {}
|
try { proc.destroy() } catch (_) {}
|
||||||
|
try { timeoutTimer.destroy() } catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
proc.running = true
|
proc.running = true
|
||||||
|
timeoutTimer.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool dsearchAvailable: false
|
property bool dsearchAvailable: false
|
||||||
property int requestIdCounter: 0
|
property int searchIdCounter: 0
|
||||||
|
|
||||||
signal searchResultsReceived(var results)
|
signal searchResultsReceived(var results)
|
||||||
signal statsReceived(var stats)
|
signal statsReceived(var stats)
|
||||||
@@ -121,6 +121,12 @@ Singleton {
|
|||||||
callback({ "error": error })
|
callback({ "error": error })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (exitCode === 124) {
|
||||||
|
const error = "search timed out"
|
||||||
|
errorOccurred(error)
|
||||||
|
if (callback) {
|
||||||
|
callback({ "error": error })
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const error = "search failed"
|
const error = "search failed"
|
||||||
errorOccurred(error)
|
errorOccurred(error)
|
||||||
@@ -128,160 +134,7 @@ Singleton {
|
|||||||
callback({ "error": error })
|
callback({ "error": error })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 100, 5000)
|
||||||
}
|
|
||||||
|
|
||||||
function getStats(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-stats", ["dsearch", "stats", "--json"], (stdout, exitCode) => {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
statsReceived(response)
|
|
||||||
if (callback) {
|
|
||||||
callback({ "result": response })
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
const error = "failed to parse stats response"
|
|
||||||
errorOccurred(error)
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": error })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const error = "stats failed"
|
|
||||||
errorOccurred(error)
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": error })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function sync(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-sync", ["dsearch", "sync", "--json"], (stdout, exitCode) => {
|
|
||||||
if (callback) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
callback({ "result": response })
|
|
||||||
} catch (e) {
|
|
||||||
callback({ "error": "failed to parse sync response" })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback({ "error": "sync failed" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function reindex(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-reindex", ["dsearch", "reindex", "--json"], (stdout, exitCode) => {
|
|
||||||
if (callback) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
callback({ "result": response })
|
|
||||||
} catch (e) {
|
|
||||||
callback({ "error": "failed to parse reindex response" })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback({ "error": "reindex failed" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchStart(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-watch-start", ["dsearch", "watch", "start", "--json"], (stdout, exitCode) => {
|
|
||||||
if (callback) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
callback({ "result": response })
|
|
||||||
} catch (e) {
|
|
||||||
callback({ "error": "failed to parse watch start response" })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback({ "error": "watch start failed" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchStop(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-watch-stop", ["dsearch", "watch", "stop", "--json"], (stdout, exitCode) => {
|
|
||||||
if (callback) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
callback({ "result": response })
|
|
||||||
} catch (e) {
|
|
||||||
callback({ "error": "failed to parse watch stop response" })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback({ "error": "watch stop failed" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchStatus(callback) {
|
|
||||||
if (!dsearchAvailable) {
|
|
||||||
if (callback) {
|
|
||||||
callback({ "error": "dsearch not available" })
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Proc.runCommand("dsearch-watch-status", ["dsearch", "watch", "status", "--json"], (stdout, exitCode) => {
|
|
||||||
if (callback) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
try {
|
|
||||||
const response = JSON.parse(stdout)
|
|
||||||
callback({ "result": response })
|
|
||||||
} catch (e) {
|
|
||||||
callback({ "error": "failed to parse watch status response" })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback({ "error": "watch status failed" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function rediscover() {
|
function rediscover() {
|
||||||
|
|||||||
Reference in New Issue
Block a user