Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions packages/opencode/src/file/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,29 @@ export namespace FileWatcher {
return createWrapper(binding) as typeof import("@parcel/watcher")
})

// WORKAROUND: Timeout for watcher subscribe - hangs indefinitely on x86 emulation via Rosetta (parcel-bundler/watcher#159)
// On timeout: no auto-detection of branch switches or external file changes
const SUBSCRIBE_TIMEOUT_MS = 5000

async function subscribeWithTimeout(
dir: string,
callback: ParcelWatcher.SubscribeCallback,
options: Parameters<typeof ParcelWatcher.subscribe>[2],
): Promise<ParcelWatcher.AsyncSubscription | null> {
const timeout = new Promise<null>((resolve) => {
setTimeout(() => {
log.error("watcher subscribe timeout", { dir })
resolve(null)
}, SUBSCRIBE_TIMEOUT_MS)
})
try {
return await Promise.race([watcher().subscribe(dir, callback, options), timeout])
} catch (e) {
log.warn("watcher subscribe failed", { dir, error: e })
return null
}
}
Comment thread
rekram1-node marked this conversation as resolved.

const state = Instance.state(
async () => {
if (Instance.project.vcs !== "git") return {}
Expand All @@ -57,11 +80,11 @@ export namespace FileWatcher {
}
}

const subs = []
const subs: (ParcelWatcher.AsyncSubscription | null)[] = []
const cfgIgnores = cfg.watcher?.ignore ?? []

subs.push(
await watcher().subscribe(Instance.directory, subscribe, {
await subscribeWithTimeout(Instance.directory, subscribe, {
ignore: [...FileIgnore.PATTERNS, ...cfgIgnores],
backend,
}),
Expand All @@ -70,7 +93,7 @@ export namespace FileWatcher {
const vcsDir = await $`git rev-parse --git-dir`.quiet().nothrow().cwd(Instance.worktree).text()
if (vcsDir && !cfgIgnores.includes(".git") && !cfgIgnores.includes(vcsDir)) {
subs.push(
await watcher().subscribe(vcsDir, subscribe, {
await subscribeWithTimeout(vcsDir, subscribe, {
ignore: ["hooks", "info", "logs", "objects", "refs", "worktrees", "modules", "lfs"],
backend,
}),
Expand Down