Skip to main content

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

┌─────────────────────────────────────────────────────────────────────┐
│               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/ directories
  • node_modules/
  • Build artifacts (target/, dist/, build/)
  • Temporary files (*.tmp, *.swp)
  • OS files (.DS_Store, Thumbs.db)

Event Batching

Debounces rapid file changes:
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

PlatformBackend
macOSFSEvents
Linuxinotify
WindowsReadDirectoryChangesW

Events

Event Types

┌─────────────────────────────────────────────────────────────────┐
│  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

┌─────────────────────────────────────────────────────────────────┐
│  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

┌─────────────────────────────────────────────────────────────────┐
│  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:
.git/**
node_modules/**
target/**
dist/**
build/**
*.tmp
*.swp
.DS_Store
Thumbs.db
Custom patterns can be added via configuration.

Usage

Starting the Watcher

┌─────────────────────────────────────────────────────────────────┐
│  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

┌─────────────────────────────────────────────────────────────────┐
│  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

┌─────────────────────────────────────────────────────────────────┐
│  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

MetricValue
Binary size2.75MB
Memory usageLow
Event latencyFast
Watched pathsScalable
ThroughputHigh

Logging

┌─────────────────────────────────────────────────────────────────┐
│  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

┌─────────────────────────────────────────────────────────────────┐
│  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

  1. Check if path is being watched
  2. Verify path isn’t ignored by filters
  3. Check event batching delay
  4. Review watcher logs

High CPU Usage

Usually caused by:
  • Watching too many files
  • Rapid file changes (reduce debounce time)
  • Recursive watch on large directories
Solution: Add ignore patterns for noisy directories.

SMPC/OFAC Applied

PrincipleApplication
SMPCSingle purpose: file watching only
Simple event types: create/modify/delete/rename
Clear ignore patterns
OFACBatching emerged from event storm handling
Filtering emerged from noise reduction need
Database storage emerged from persistence need