NIIA Watcher Daemon
The NIIA Watcher daemon monitors file system changes with intelligent filtering and event batching, providing real-time updates to the Monolex application.Overview
Copy
┌─────────────────────────────────────────────────────────────────────┐
│ NIIA WATCHER ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ File System │
│ │ │
│ │ inotify (Linux) / FSEvents (macOS) / ReadDirectoryChanges │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ niia-watcher-daemon (2.75MB) │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ Event │───→│ Filter │───→│ Batcher │ │ │
│ │ │ Collector │ │ Engine │ │ (debounce) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │ │
│ └─────────────────────────────────────────────────│───────────┘ │
│ ▼ │
│ Unix Socket ───────────────────────────────────────────────────── │
│ │ │
│ Tauri App │ │
│ ┌─────────────────────────────────────────────────│───────────┐ │
│ │ WatcherClient ▼ │ │
│ │ ├── on_create(path) │ │
│ │ ├── on_modify(path) │ │
│ │ ├── on_delete(path) │ │
│ │ └── on_rename(old_path, new_path) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Features
Intelligent Filtering
Pre-configured ignore patterns:.git/directoriesnode_modules/- Build artifacts (
target/,dist/,build/) - Temporary files (
*.tmp,*.swp) - OS files (
.DS_Store,Thumbs.db)
Event Batching
Debounces rapid file changes:Copy
File saved 5 times in 100ms:
├── Modify event 1 (t=0ms)
├── Modify event 2 (t=20ms)
├── Modify event 3 (t=40ms)
├── Modify event 4 (t=60ms)
└── Modify event 5 (t=80ms)
With batching (50ms debounce):
└── Single batched event (t=130ms)
Cross-Platform Support
| Platform | Backend |
|---|---|
| macOS | FSEvents |
| Linux | inotify |
| Windows | ReadDirectoryChangesW |
Events
Event Types
Copy
┌─────────────────────────────────────────────────────────────────┐
│ WATCHER EVENT TYPES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Event Data Example │
│ ─────────── ──────────────────────── ───────────── │
│ Create path /src/new.rs │
│ Modify path /src/main.rs │
│ Delete path /src/old.rs │
│ Rename old_path, new_path foo.rs → bar.rs │
│ │
└─────────────────────────────────────────────────────────────────┘
Event Format
Copy
┌─────────────────────────────────────────────────────────────────┐
│ EVENT DATA STRUCTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Event received via Unix Socket │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Event Type │ File Path │ Timestamp │ │
│ ├────────────────┼──────────────────┼─────────────────────┤ │
│ │ modify │ src/main.rs │ When it happened │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Tauri receives and processes each event │
│ │
└─────────────────────────────────────────────────────────────────┘
Configuration
Watch Paths
Copy
┌─────────────────────────────────────────────────────────────────┐
│ WATCH PATH MANAGEMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Add Watch: │
│ └── watcher_add_path("/Users/user/project") │
│ └── Recursive by default (all subdirectories) │
│ │
│ Remove Watch: │
│ └── watcher_remove_path("/Users/user/project") │
│ └── Stops monitoring that path │
│ │
└─────────────────────────────────────────────────────────────────┘
Ignore Patterns
Default patterns:Copy
.git/**
node_modules/**
target/**
dist/**
build/**
*.tmp
*.swp
.DS_Store
Thumbs.db
Usage
Starting the Watcher
Copy
┌─────────────────────────────────────────────────────────────────┐
│ STARTING THE WATCHER │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. Start watcher daemon │
│ └── invoke("start_watcher") │
│ │
│ 2. Add paths to watch │
│ └── invoke("watcher_add_path", { path: "/project" }) │
│ │
│ 3. Watcher now monitoring file system changes │
│ │
└─────────────────────────────────────────────────────────────────┘
Listening to Events
Copy
┌─────────────────────────────────────────────────────────────────┐
│ EVENT LISTENER FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ listen("watcher-event", callback) │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Event received: { type, path } │ │
│ └───────────────────────┬─────────────────────────────────┘ │
│ │ │
│ ┌────────────┬────┴────┬─────────────┐ │
│ ▼ ▼ ▼ ▼ │
│ create modify delete rename │
│ │ │ │ │ │
│ File created File saved File removed File renamed │
│ │
│ Frontend updates UI based on event type │
│ │
└─────────────────────────────────────────────────────────────────┘
Database Integration
Copy
┌─────────────────────────────────────────────────────────────────┐
│ EVENT PERSISTENCE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ File Event │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────────────────────────┐ │
│ │ Watcher │────────▶│ SQLite Database │ │
│ │ Daemon │ │ │ │
│ └─────────────┘ │ ┌───────────────────────────┐ │ │
│ │ │ Watcher Events │ │ │
│ │ ├───────────────────────────┤ │ │
│ │ │ • Event type │ │ │
│ │ │ • File path │ │ │
│ │ │ • Timestamp │ │ │
│ │ │ • Processing status │ │ │
│ │ └───────────────────────────┘ │ │
│ │ │ │
│ │ Indexed for fast queries │ │
│ └─────────────────────────────────┘ │
│ │
│ Benefits: │
│ ✓ Event history preserved │
│ ✓ Survives app restarts │
│ ✓ Fast path-based queries │
│ │
└─────────────────────────────────────────────────────────────────┘
Characteristics
| Metric | Value |
|---|---|
| Binary size | 2.75MB |
| Memory usage | Low |
| Event latency | Fast |
| Watched paths | Scalable |
| Throughput | High |
Logging
Copy
┌─────────────────────────────────────────────────────────────────┐
│ WATCHER LOG FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Daemon starts │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ INFO Starting NIIA Watcher │ │
│ │ INFO Watching: /project │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ File change detected │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ DEBUG File modified: src/main.rs │ │
│ │ DEBUG Event batched, waiting 50ms │ │
│ │ INFO Emitting batched event for src/main.rs │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Log levels: INFO (general) → DEBUG (detailed) │
│ │
└─────────────────────────────────────────────────────────────────┘
Troubleshooting
Watcher Not Starting
Copy
┌─────────────────────────────────────────────────────────────────┐
│ TROUBLESHOOTING CHECKLIST │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Check if daemon is already running │
│ ───────────────────────────────────────────── │
│ □ Look for niia-watcher process │
│ □ If running, restart may be needed │
│ │
│ Step 2: Review daemon logs │
│ ───────────────────────────────────────────── │
│ □ Check for startup errors │
│ □ Look for permission issues │
│ │
│ Step 3: Verify binary installation │
│ ───────────────────────────────────────────── │
│ □ Daemon binary should exist in binaries folder │
│ □ Binary should be code-signed (macOS) │
│ │
└─────────────────────────────────────────────────────────────────┘
Events Not Firing
- Check if path is being watched
- Verify path isn’t ignored by filters
- Check event batching delay
- Review watcher logs
High CPU Usage
Usually caused by:- Watching too many files
- Rapid file changes (reduce debounce time)
- Recursive watch on large directories
SMPC/OFAC Applied
| Principle | Application |
|---|---|
| SMPC | Single purpose: file watching only |
| Simple event types: create/modify/delete/rename | |
| Clear ignore patterns | |
| OFAC | Batching emerged from event storm handling |
| Filtering emerged from noise reduction need | |
| Database storage emerged from persistence need |