Class WorkspaceWatcher

Namespace
Kuestenlogik.Bowire.Workspace.Git
Assembly
Kuestenlogik.Bowire.Workspace.Git.dll

Singleton watcher fleet — keeps one FileSystemWatcher per watched storageRoot and fans events out to every subscriber listening on that root. The SSE endpoint (#150) gets a ChannelReader<T> per subscription so each connected browser tab consumes its own queue.

public sealed class WorkspaceWatcher : IAsyncDisposable
Inheritance
WorkspaceWatcher
Implements
Inherited Members

Remarks

Events are debounced per-path at DebounceMilliseconds: the noisy save-shuffle from editors (temp-file dance, attribute touches) collapses to one logical "this path changed" notification before reaching subscribers. Each path's pending dispatch carries its own CancellationTokenSource; a fresh FS event for the same path cancels the in-flight delay and starts a new one, so a steady stream of writes only fires once after the writer goes quiet.

Reference-counted: when the last subscriber on a root unsubscribes the underlying FileSystemWatcher is disposed. Re- subscribing later spins up a fresh watcher. This keeps a CLI / web process from leaking watchers when the operator switches workspaces.

Constructors

WorkspaceWatcher()

public WorkspaceWatcher()

Fields

DebounceMilliseconds

Debounce window for per-path event coalescing.

public const int DebounceMilliseconds = 300

Field Value

int

Methods

DisposeAsync()

public ValueTask DisposeAsync()

Returns

ValueTask

Subscribe(string)

Subscribe to file-system events on storageRoot. Returns the channel reader the SSE producer streams from and an IDisposable that, when disposed, unsubscribes and (if last) tears down the underlying watcher.

public (ChannelReader<WorkspaceFileEvent> Reader, IDisposable Subscription) Subscribe(string storageRoot)

Parameters

storageRoot string

Returns

(ChannelReader<WorkspaceFileEvent> Reader, IDisposable Subscription)

Exceptions

ArgumentException

storageRoot is null / empty, doesn't exist, or isn't a directory. The watcher refuses to create a watcher on a missing path so the failure surfaces immediately to the SSE caller instead of as a silent zero-event stream.