Overview
Hot reload enables configuration changes to take effect without restarting pods. The client libraries automatically detect when values files are updated and reload them with validation, providing a seamless update experience. Changes propagate through the system in minutes, with full observability into timing and delays.Reload lifecycle
The complete reload cycle from code commit to active values:No pod restart is required. The application continues running with updated configuration.
File watching implementation
Polling strategy
The client libraries use polling instead of filesystem events (inotify/FSEvents):- Polling interval: 5 seconds (POLLING_DELAY constant in lib.rs:30)
- Mechanism: Check modification time of all values.json files
- Reload trigger: Any file mtime change triggers full reload
- Works reliably with Kubernetes ConfigMaps (which don’t trigger inotify events)
- Compatible with NFS and other virtual filesystems
- Simple implementation with predictable behavior
- 5 seconds is acceptable overhead given ~1-2 min ConfigMap propagation
Watcher thread
TheValuesWatcher struct (lib.rs:483-672) runs a background thread:
- Created during
Options::new()initialization - Spawns background thread named
"sentry-options-watcher" - Thread polls every 5 seconds until stopped
- Automatically stopped when
ValuesWatcheris dropped
- Values stored in
Arc<RwLock<ValuesByNamespace>> - Multiple readers can access values concurrently
- Writer (reload thread) gets exclusive access during updates
- If thread panics, it’s caught and logged (lib.rs:509-515)
Modification time tracking
The watcher tracks the most recent modification time across all namespace values.json files:Reload behavior
Atomic updates
When a change is detected:- Load all values from disk into new HashMap
- Validate all namespaces against schemas
- If all valid: Replace entire values map atomically
- If any invalid: Keep old values entirely, log error
Validation during reload
All values are re-validated against schemas on every reload:- Read all
{namespace}/values.jsonfiles - Parse JSON and extract
optionsobject - Validate each namespace’s options against its schema
- If validation passes for all namespaces, update values
- If any validation fails, keep old values and log error
Reader/writer synchronization
The values map usesRwLock for concurrent access:
- Readers (application code calling
opts.get()): Multiple concurrent reads allowed - Writer (reload thread): Exclusive write access blocks all readers
- Poisoning handled: If lock is poisoned (writer panicked), readers still work (lib.rs:79)
Propagation timing
ConfigMap propagation delay
Kubernetes takes time to sync ConfigMap updates to pods:- Kubelet sync period: Default ~1 minute (configurable)
- Cache TTL: Additional delay from kubelet cache
- Total typical delay: 1-2 minutes from
kubectl applyto file update
Total end-to-end latency
Observability metrics
The reload process emits detailed timing metrics via Sentry transactions.Observability
Sentry integration
The validation library includes a dedicated Sentry Hub for tracking reloads (lib.rs:42-63):- Completely isolated from host application’s Sentry setup
- Uses separate DSN and client configuration
- 100% sample rate for all reload transactions
- Disabled in tests (empty DSN)
Reload transactions
One transaction emitted per namespace on each reload (lib.rs:612-644):Available metrics
| Metric | Description | Source |
|---|---|---|
reload_duration_ms | Time to load and validate values | Measured in reload function |
generated_at | When ConfigMap was generated | From values.json metadata |
applied_at | When application loaded values | Current timestamp |
propagation_delay_secs | Time from generation to application | Calculated: applied_at - generated_at |
"seer", "relay")
Transaction type: "sentry_options.reload"
Sample rate: 100% (all reloads tracked)
Propagation delay tracking
Thegenerated_at timestamp is embedded in values.json by the CLI:
- How long ConfigMaps took to propagate to pods
- Bottlenecks in the deployment pipeline
- Whether kubelet sync is slower than expected
Error handling
Missing values directory
If the values directory doesn’t exist:- Watcher creation: Logs warning but continues (lib.rs:496-498)
- Polling: Returns
Nonefor mtime, no reload triggered - Application: Uses schema defaults for all options
SENTRY_OPTIONS_SUPPRESS_MISSING_DIR=1 to suppress warnings.
Validation failures
If reloaded values fail validation:-
Error logged to stderr:
- Old values retained - application continues with previous configuration
- No Sentry transaction emitted (only on successful reload)
Thread panics
If the watcher thread panics:- Panic is caught and logged
- Thread terminates
- No new reloads occur
- Application continues with last known values
Lock poisoning
If the reload thread panics while holding the write lock:Testing hot reload
Local testing
To test hot reload locally:-
Create test values:
-
Start your application:
-
Modify values while running:
-
Observe reload:
- Within 5 seconds, application prints
enabled: True - No restart required
- Within 5 seconds, application prints
Reload timing tests
The test suite includes timing tests (lib.rs:1319-1386):- Modification time detection
- Atomic value updates
- Old values persist on validation errors
- Thread creation and termination
Best practices
Graceful value changes
When changing configuration:- Consider active requests: Values can change mid-request
- Use circuit breakers: For critical flags that affect traffic routing
- Monitor metrics: Watch Sentry transactions to confirm propagation
- Test locally first: Verify reload works with your schema
Reload-safe code patterns
Monitoring reload health
Query Sentry transactions to track reload behavior:- Propagation delays: Check
propagation_delay_secsdistribution - Reload frequency: Count transactions per namespace
- Reload duration: Monitor
reload_duration_msfor performance
- Propagation delays > 5 minutes (indicates kubelet sync issues)
- Reload duration > 1 second (indicates slow disk or large values)
- Missing reload transactions (watcher thread may be dead)