Help us shape the future of Go! Take the 2026 Go Developer Survey

fswatch

package
v1.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package fswatch provides shared helpers for Pando's recursive filesystem watchers. On macOS fsnotify uses kqueue, which costs one file descriptor per watched directory and per file inside it, so every watcher must skip heavy, generated and ignored directories BEFORE calling fsnotify's Add.

Index

Constants

View Source
const WarnThreshold = 10000

WarnThreshold is the estimated file-descriptor cost above which a watcher logs a one-time warning.

Variables

This section is empty.

Functions

func CodeWatchLockPath

func CodeWatchLockPath(workdir string) string

CodeWatchLockPath returns the per-project lock file that guards the startup code index and recursive filesystem watcher: <workdir>/.pando/code-watch.lock.

func DefaultExcludedDirs

func DefaultExcludedDirs() []string

DefaultExcludedDirs returns the sorted built-in directory names and suffix globs (for example "*.dSYM") that are excluded from watching.

func EstimateCost

func EstimateCost(goos string, dirs, files int) int

EstimateCost returns the estimated number of file descriptors (or kernel watches) needed to watch dirs directories holding files regular files. kqueue platforms (macOS, BSD) spend one descriptor per directory AND per file; inotify (Linux) and others only count directories.

func TryLock

func TryLock(path string) (release func(), ok bool, err error)

TryLock takes a non-blocking exclusive flock on path. ok is false when another open file description (in this or another process) holds it. The lock is released automatically if the process dies. release is idempotent.

func TryLockDir

func TryLockDir(workdir string) (release func(), ok bool, err error)

TryLockDir creates <workdir>/.pando if needed and tries to take the non-blocking exclusive code-watch lock for workdir. See TryLock.

Types

type Excluder

type Excluder struct {
	// contains filtered or unexported fields
}

Excluder decides which directories a watcher must not register. It is safe for concurrent use.

func NewExcluder

func NewExcluder(root string, extra []string) *Excluder

NewExcluder builds an Excluder for the watch root. extra holds user patterns (the WatchExclude config): plain directory names or doublestar globs relative to root, e.g. "mobile-app/www/svg" or "**/generated".

func (*Excluder) ShouldSkipDir

func (e *Excluder) ShouldSkipDir(absPath string) bool

ShouldSkipDir reports whether the directory at absPath must not be watched. The root itself is never skipped. When a directory is kept, its own .gitignore/.pandoignore are loaded so they apply to its children.

type Hub

type Hub struct {
	// contains filtered or unexported fields
}

Hub owns ONE recursive fsnotify watcher for a workspace and fans every event out to any number of subscribers.

On macOS (kqueue) fsnotify spends one file descriptor per watched directory and per file inside it, so each extra full-tree watcher multiplies the FD cost. Sharing one watcher keeps that cost constant regardless of how many consumers (LSP clients, the bootstrap watcher, ...) exist.

Lifecycle: the underlying watcher is started lazily by the first Subscribe and keeps running until Close (app shutdown), even if every subscriber leaves. LSP restarts unsubscribe and resubscribe in quick succession, and tearing the tree down and re-walking it each time would be wasteful.

func NewHub

func NewHub(root string, excluder *Excluder) *Hub

NewHub creates a hub for root. excluder decides which directories are never watched; when nil one is built from the defaults.

func (*Hub) Close

func (h *Hub) Close()

Close stops the shared watcher and closes every subscription. It blocks until the watcher goroutine has released its file descriptors.

func (*Hub) Excluder

func (h *Hub) Excluder() *Excluder

Excluder returns the directory excluder used by the hub.

func (*Hub) PathCount

func (h *Hub) PathCount() int

PathCount returns how many directories are currently registered with the underlying fsnotify watcher (kept in sync on removals).

func (*Hub) Root

func (h *Hub) Root() string

Root returns the watched workspace root.

func (*Hub) Subscribe

func (h *Hub) Subscribe() *Subscription

Subscribe registers a new subscriber, starting the shared watcher on first use. It returns nil when the hub is closed.

func (*Hub) SubscriberCount

func (h *Hub) SubscriberCount() int

SubscriberCount returns the number of active subscriptions.

type Subscription

type Subscription struct {
	// Events delivers every filesystem event the hub observes. It is closed
	// when the subscription is closed or the hub is shut down.
	Events <-chan fsnotify.Event
	// contains filtered or unexported fields
}

Subscription receives the events of a Hub until Close is called.

func (*Subscription) Close

func (s *Subscription) Close()

Close unsubscribes; no further events are delivered and Events is closed.

func (*Subscription) Dropped

func (s *Subscription) Dropped() int64

Dropped returns how many events were discarded because the subscriber was too slow.

type WatchBudget

type WatchBudget struct {
	// contains filtered or unexported fields
}

WatchBudget tracks the watch cost of one watcher instance and warns once when it exceeds the threshold. It is safe for concurrent use.

func NewWatchBudget

func NewWatchBudget(name, root string) *WatchBudget

NewWatchBudget creates a budget for the named watcher ("lsp-workspace", "code-index", ...) rooted at root.

func (*WatchBudget) AddDir

func (b *WatchBudget) AddDir()

AddDir records one watched directory. Nil-safe.

func (*WatchBudget) AddFile

func (b *WatchBudget) AddFile()

AddFile records one file living directly inside a watched directory. Nil-safe.

func (*WatchBudget) Check

func (b *WatchBudget) Check() bool

Check logs a single warning (per budget) when the estimate exceeds the threshold. It returns true when the warning was emitted by this call.

func (*WatchBudget) Cost

func (b *WatchBudget) Cost() int

Cost returns the current estimated FD cost.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL