NAME
Developer::Dashboard::IndicatorStore::Watch - optional filesystem event adapter
PURPOSE
Provides a small, nonblocking event watcher used to validate stable indicator and configuration filesystem snapshots when a native backend is available. The native Linux adapter uses libc inotify through the optional FFI::Platypus distribution. Tests and other platform adapters can inject a path-configuring backend with nonblocking poll and close callbacks. Unsupported systems use the caller's portable metadata/content validator instead of disabling snapshot reuse.
WHY IT EXISTS
The stable collector-sync path checks directory inventories and high-resolution status-file signatures so that another process's writes are observed on the next request. For large inventories, those checks repeat directory reads and metadata syscalls. An event can prove that a portable full validation is needed; an event-free matching watch set can safely skip those checks after its snapshot has been established. Events are treated conservatively: the adapter does not interpret filenames or event masks, so overflow, rename, delete, and write events all invalidate the fast path.
WHEN TO USE
Use this adapter only as an optimization hint around a previously validated filesystem snapshot. Callers must retain portable validation when the backend is unavailable, a watch cannot be installed, the inventory signature changes, or any event is observed. Configuration snapshots use directory metadata plus SHA-256 of exact config files on unsupported systems; this detects additions, removals, and in-place edits without requiring Linux-specific APIs.
HOW TO USE
my $watch = Developer::Dashboard::IndicatorStore::Watch->new;
if ($watch) {
$watch->configure( $signature, \@directories );
my $unchanged = $watch->unchanged($signature);
}
Unsupported systems do not load native modules. Linux uses FFI::Platypus for inotify, macOS optionally uses Mac::FSEvents, and Windows uses FFI::Platypus with wide-character directory notification APIs. Missing optional modules return undef from the default constructor; failures in installed bindings remain visible.
WHAT USES IT
Developer::Dashboard::IndicatorStore may use the adapter for its stable collector synchronization. The repository tests use an injected backend to exercise event and error handling without relying on Linux or FFI installation.
EXAMPLES
Example 1: build the optional native backend when available.
my $watch = Developer::Dashboard::IndicatorStore::Watch->new;
Example 2: establish an inventory snapshot.
$watch->configure( $inventory_signature, [ $root, @indicator_directories ] );
Example 3: invalidate and use the ordinary validator after any event.
if ( !$watch->unchanged($inventory_signature) ) {
validate_directory_inventory_and_file_signatures();
}
Example 4: run its deterministic contract test.
prove -lv t/669-problem48-inotify-watch.t
SAFETY
The adapter executes no shell commands and reads no status-file content. It does not treat a failed or event-bearing watch as unchanged. Linux paths are passed to libc only when they can be represented without lossy byte conversion. macOS uses FSEvents when Mac::FSEvents is installed; Windows uses wide-character directory notifications through FFI::Platypus. Each optional backend falls back to the caller's portable validator when unavailable.