mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 06:00:33 +02:00
Fix the follow-up review's findings
- Pairing saves nothing if it was cancelled while adding the key. - The ssh stand-in runs under bash: dash refuses job control without a terminal, which cost stdin and the process group. - A server that stops while the tunnel opens fails the attempt (and retries) instead of leaving it half-connected. - The health probe answers within its deadline even when a dead link keeps the probe itself waiting. - A cached version is deleted only if no server runs from it (servers now run by absolute path) and it's two weeks unused. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a910f83ac1
commit
14790ac768
4 files changed
+31
-18
No files matched your search
@@ -80,15 +80,15 @@ final class FrameLink: @unchecked Sendable {
|
||||
|
||||
var isConnected: Bool { client.isConnected }
|
||||
|
||||
/// Whether the Frame answers a trivial command within a few seconds.
|
||||
/// Whether the Frame answers a trivial command within a few seconds. The probe
|
||||
/// runs unstructured: a dead link can keep it waiting well past the deadline,
|
||||
/// and the answer mustn't wait for it.
|
||||
func answers(within seconds: Double = 6) async -> Bool {
|
||||
guard client.isConnected else { return false }
|
||||
return await withTaskGroup(of: Bool.self) { group in
|
||||
group.addTask { (try? await self.run("true").status) == 0 }
|
||||
group.addTask { try? await Task.sleep(nanoseconds: UInt64(seconds * 1e9)); return false }
|
||||
let first = await group.next() ?? false
|
||||
group.cancelAll()
|
||||
return first
|
||||
let once = Once()
|
||||
return await withCheckedContinuation { (c: CheckedContinuation<Bool, Never>) in
|
||||
Task { let ok = (try? await self.run("true").status) == 0; if once.claim() { c.resume(returning: ok) } }
|
||||
Task { try? await Task.sleep(nanoseconds: UInt64(seconds * 1e9)); if once.claim() { c.resume(returning: false) } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,13 @@ final class FrameLink: @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// True for the first caller only.
|
||||
final class Once: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
private var done = false
|
||||
func claim() -> Bool { lock.withLock { defer { done = true }; return !done } }
|
||||
}
|
||||
|
||||
func shellQuote(_ s: String) -> String {
|
||||
"'" + s.replacingOccurrences(of: "'", with: "'\\''") + "'"
|
||||
}
|
||||
@@ -69,18 +69,20 @@ final class HeadsetServer: @unchecked Sendable {
|
||||
try await link.check("rm -rf \(dir).tmp && mkdir \(dir).tmp && tar xzf \(archive) -C \(dir).tmp && rm -f \(archive) "
|
||||
+ "&& rm -rf \(dir) && mv \(dir).tmp \(dir)", "Couldn't unpack Frame Control on the headset")
|
||||
}
|
||||
// Another phone or iPad may be running a different version right now, so only
|
||||
// versions (and interrupted unpacks) untouched for two weeks go. This one is
|
||||
// marked as used.
|
||||
_ = try? await link.run("touch \(dir) && find \(cacheDir) -mindepth 1 -maxdepth 1 -type d ! -name \(bundle.version) "
|
||||
+ "-mtime +14 -exec rm -rf {} +")
|
||||
// Another phone or iPad may be running a different version right now: a version
|
||||
// goes only when no server runs from it and it hasn't been used for two weeks
|
||||
// (this one is marked as used). Servers run by absolute path, so pgrep sees it.
|
||||
_ = try? await link.run("touch \(dir) && cd \(cacheDir) && for d in */; do d=${d%/}; "
|
||||
+ "[ \"$d\" = \(bundle.version) ] && continue; "
|
||||
+ "[ -n \"$(find \"$d\" -maxdepth 0 -mtime +14)\" ] || continue; "
|
||||
+ "pgrep -f \"$PWD/$d/\" >/dev/null && continue; rm -rf -- \"$d\"; done")
|
||||
return dir
|
||||
}
|
||||
|
||||
/// Starts the server in dir and waits for it to say which port it took.
|
||||
static func start(in dir: String, over link: FrameLink, key: String, device: String) async throws -> HeadsetServer {
|
||||
let command = "cd \(dir) && FRAME_LOCAL=1 FRAME_UI_KEY=\(key) FRAME_DEVICE=\(shellQuote(device)) "
|
||||
+ "exec python3 -I -u -B ui/server.py --port 0 --exit-on-eof 2>&1"
|
||||
+ "exec python3 -I -u -B \"$PWD/ui/server.py\" --port 0 --exit-on-eof 2>&1"
|
||||
let stream = try await link.client.executeCommandStream(command)
|
||||
let box = PortWaiter()
|
||||
let reader = Task { () -> Void in
|
||||
|
||||
Reference in new issue
Block a user