docs(daemon): update event-driven mode documentation

- Update Event-Driven Daemon Mode section from 'Experimental' to 'Default'
- Document that event-driven mode is default since v0.21.0
- Add detailed architecture diagram showing export and import flows
- Add remote-sync-interval configuration section with examples
- Document BEADS_REMOTE_SYNC_INTERVAL environment variable
- Add config.yaml example for remote-sync-interval
- Update 'Enabling Event-Driven Mode' to reflect default behavior
- Add 'Switch to Polling Mode' section for edge cases

The documentation now accurately reflects the current implementation where
event-driven mode is the default and includes periodic remote sync for
multi-clone workflows.
This commit is contained in:
Charles P. Cross
2025-12-22 18:49:46 -05:00
parent 4c38075520
commit ca348a29cb
+81 -33
View File
@@ -185,9 +185,9 @@ bd ready
- Socket file stale: `rm .beads/bd.sock` (auto-cleans on next start) - Socket file stale: `rm .beads/bd.sock` (auto-cleans on next start)
- Multiple bd versions installed: `which bd` and `bd version` - Multiple bd versions installed: `which bd` and `bd version`
## Event-Driven Daemon Mode (Experimental) ## Event-Driven Daemon Mode (Default)
**NEW in v0.16+**: Event-driven mode replaces 5-second polling with instant reactivity. **Default since v0.21.0**: Event-driven mode replaces 5-second polling with instant reactivity.
### Benefits ### Benefits
@@ -195,19 +195,39 @@ bd ready
- 🔋 **~60% less CPU usage** (no continuous polling) - 🔋 **~60% less CPU usage** (no continuous polling)
- 🎯 **Instant sync** on mutations and file changes - 🎯 **Instant sync** on mutations and file changes
- 🛡️ **Dropped events safety net** prevents data loss - 🛡️ **Dropped events safety net** prevents data loss
- 🔄 **Periodic remote sync** pulls updates from other clones
### How It Works ### How It Works
**Architecture:** **Architecture:**
``` ```
FileWatcher (platform-native) ┌─────────────────────────────────────────────────────────────────┐
├─ .beads/issues.jsonl (file changes) │ EVENT-DRIVEN MODE │
├─ .git/refs/heads (git updates) ├─────────────────────────────────────────────────────────────────┤
└─ RPC mutations (create, update, close) │ │
│ ┌──────────────────────────────────────────────────────────┐ │
Debouncer (500ms batch window) │ │ EXPORT FLOW (Mutation-Triggered) │ │
│ │ │ │
Export → Git Commit/Push │ │ FileWatcher (platform-native) │ │
│ │ ├─ .beads/issues.jsonl (file changes) │ │
│ │ └─ RPC mutations (create, update, close) │ │
│ │ ↓ │ │
│ │ Debouncer (500ms batch window) │ │
│ │ ↓ │ │
│ │ Export → Git Commit → Git Push (if --auto-push) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ IMPORT FLOW (Periodic Remote Sync) │ │
│ │ │ │
│ │ remoteSyncTicker (default: 30s, configurable) │ │
│ │ ↓ │ │
│ │ Git Pull (from sync branch or origin) │ │
│ │ ↓ │ │
│ │ Import JSONL → Database │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
``` ```
**Platform-native APIs:** **Platform-native APIs:**
@@ -215,29 +235,26 @@ FileWatcher (platform-native)
- macOS: `FSEvents` (via kqueue) - macOS: `FSEvents` (via kqueue)
- Windows: `ReadDirectoryChangesW` - Windows: `ReadDirectoryChangesW`
**Mutation events** from RPC trigger immediate export **Key behaviors:**
**Debouncer** batches rapid changes (500ms window) to avoid export storms - **Mutation events** from RPC trigger immediate export (debounced 500ms)
**Polling fallback** if fsnotify unavailable (network filesystems) - **Periodic remote sync** pulls updates from other clones (default 30s interval)
- **Polling fallback** if fsnotify unavailable (network filesystems)
### Enabling Event-Driven Mode ### Enabling Event-Driven Mode
**Opt-In (Phase 1):** Event-driven mode is the **default** as of v0.21.0. No configuration needed.
```bash ```bash
# Enable for single daemon # Event-driven mode starts automatically
bd daemon --start
# Explicitly enable (same as default)
BEADS_DAEMON_MODE=events bd daemon --start BEADS_DAEMON_MODE=events bd daemon --start
# Set globally in shell profile
export BEADS_DAEMON_MODE=events
# Restart all daemons to apply
bd daemons killall
# Next bd command auto-starts with new mode
``` ```
**Available modes:** **Available modes:**
- `poll` (default) - Traditional 5-second polling, stable and battle-tested - `events` (default) - Event-driven mode with instant reactivity
- `events` - Event-driven mode, experimental but thoroughly tested - `poll` - Traditional 5-second polling, fallback for edge cases
### Configuration ### Configuration
@@ -245,25 +262,56 @@ bd daemons killall
| Variable | Values | Default | Description | | Variable | Values | Default | Description |
|----------|--------|---------|-------------| |----------|--------|---------|-------------|
| `BEADS_DAEMON_MODE` | `poll`, `events` | `poll` | Daemon operation mode | | `BEADS_DAEMON_MODE` | `poll`, `events` | `events` | Daemon operation mode |
| `BEADS_WATCHER_FALLBACK` | `true`, `false` | `true` | Fall back to polling if fsnotify fails | | `BEADS_WATCHER_FALLBACK` | `true`, `false` | `true` | Fall back to polling if fsnotify fails |
| `BEADS_REMOTE_SYNC_INTERVAL` | duration | `30s` | How often to pull from remote (event mode) |
**Disable polling fallback (require fsnotify):** **config.yaml settings:**
```bash ```yaml
# Fail if watcher unavailable (e.g., testing) # .beads/config.yaml
BEADS_WATCHER_FALLBACK=false BEADS_DAEMON_MODE=events bd daemon --start
# Interval for daemon to pull remote sync branch updates
# Accepts Go duration strings: "30s", "1m", "5m", etc.
# Minimum: 5s (values below are clamped)
# Set to "0" to disable periodic remote sync (not recommended)
remote-sync-interval: "30s"
``` ```
**Switch back to polling:** **Configuration precedence:**
1. `BEADS_REMOTE_SYNC_INTERVAL` environment variable (highest)
2. `remote-sync-interval` in `.beads/config.yaml`
3. Default: 30 seconds
### Remote Sync Interval
The `remote-sync-interval` controls how often the daemon pulls from remote to check for updates from other clones.
| Value | Use Case |
|-------|----------|
| `30s` (default) | Good balance for most workflows |
| `1m` | Lower network traffic, acceptable for solo work |
| `5m` | Very low traffic, for slow-changing projects |
| `5s` (minimum) | Fastest updates, higher network usage |
**Minimum value:** 5 seconds (lower values are clamped to prevent git rate limiting and excessive network traffic)
**Disabling remote sync:**
```bash
# Set to 0 to disable (not recommended - other clones' changes won't sync)
export BEADS_REMOTE_SYNC_INTERVAL=0
```
### Switch to Polling Mode
For edge cases (NFS, containers, WSL) where fsnotify is unreliable:
```bash ```bash
# Explicitly use polling mode # Explicitly use polling mode
BEADS_DAEMON_MODE=poll bd daemon --start BEADS_DAEMON_MODE=poll bd daemon --start
# Or unset to use default # With custom interval
unset BEADS_DAEMON_MODE bd daemon --start --interval 10s
bd daemons killall # Restart with default (poll) mode
``` ```
### Troubleshooting Event-Driven Mode ### Troubleshooting Event-Driven Mode