Enable Hot-Reload for Development¶
This guide shows you how to use hot-reload functionality to automatically restart your Gemini server when files change during development.
Development Only
Hot-reload is designed for development environments only. Never use it in production - it adds overhead and is not suitable for serving real traffic.
What is Hot-Reload?¶
Hot-reload automatically restarts your Gemini server when source files or content files change. This eliminates the need to manually stop and restart the server every time you modify your code or update your Gemini content.
Use hot-reload when:
- Developing server handlers or middleware
- Creating or editing Gemini content (
.gmifiles) - Testing configuration changes
- Iterating on server features
Key features:
- Automatic file watching with OS-native events (when available)
- Graceful server restarts on changes
- Configurable watch directories and file extensions
- Minimal performance overhead during development
Quick Start¶
Basic Usage¶
Enable hot-reload with the --reload flag:
This watches for changes in:
- Your document root (
./capsule) - The Nauyaca source directory (
src/nauyaca)
And monitors these file extensions:
.py- Python source files.gmi- Gemini text files
When you modify any matching file, the server automatically restarts.
Watch Custom Directories¶
Use --reload-dir to specify additional directories to watch:
# Watch a single custom directory
nauyaca serve ./capsule --reload --reload-dir ./my-handlers
# Watch multiple directories (repeat the flag)
nauyaca serve ./capsule --reload \
--reload-dir ./my-handlers \
--reload-dir ./templates
Default Directories Still Watched
When you specify custom directories with --reload-dir, the server ONLY watches those directories. If you want to also watch the default directories (document root and source), you must include them explicitly.
Watch Additional File Extensions¶
Use --reload-ext to watch additional file types:
# Also watch TOML configuration files
nauyaca serve ./capsule --reload --reload-ext .toml
# Watch multiple extensions
nauyaca serve ./capsule --reload \
--reload-ext .toml \
--reload-ext .txt \
--reload-ext .md
Extension Format
Extensions can be specified with or without the leading dot (.py or py both work).
Common Workflows¶
Content Development¶
When working on Gemini content:
Now edit your .gmi files - the server restarts automatically when you save.
Full-Stack Development¶
When developing both code and content:
# Watch source code and content
nauyaca serve ./capsule --reload \
--reload-dir ./src/nauyaca \
--reload-dir ./capsule
Configuration Development¶
When testing configuration changes:
# Watch config files too
nauyaca serve --config config.toml --reload \
--reload-dir ./capsule \
--reload-ext .toml
Now changes to config.toml trigger a restart.
Custom Handler Development¶
When building custom request handlers:
# Watch your handler directory and capsule
nauyaca serve ./capsule --reload \
--reload-dir ./my_handlers \
--reload-dir ./capsule
How It Works¶
File Watching Backends¶
Nauyaca uses two file watching strategies:
- watchfiles (preferred): Fast, OS-native file watching using:
inotifyon LinuxFSEventson macOS-
ReadDirectoryChangesWon Windows -
Polling (fallback): Periodically scans directories for changes
- Used when
watchfilesis not installed - Slower but works everywhere
Installing watchfiles¶
For best performance, install the watchfiles library:
If watchfiles is not available, Nauyaca automatically falls back to polling with a 1-second interval.
Restart Process¶
When files change:
- Detection: File watcher detects changes matching watched extensions
- Logging: Server logs which files changed (up to 5 shown)
- Graceful shutdown: Current server receives SIGTERM and has 10 seconds to shut down cleanly
- Force kill: If shutdown takes longer than 10 seconds, server is forcefully terminated
- Port release: Brief 0.5 second pause to allow OS to release the port
- Restart: New server process starts with the same arguments
Supervisor Architecture¶
Hot-reload uses a supervisor process pattern:
┌─────────────────────┐
│ Supervisor │ ← Main process with file watcher
│ (parent process) │
└──────────┬──────────┘
│
│ spawns
↓
┌─────────────────────┐
│ Server │ ← Server subprocess
│ (child process) │
└─────────────────────┘
The supervisor:
- Watches files for changes
- Spawns/restarts the server subprocess
- Handles SIGINT/SIGTERM for clean shutdown
- Manages server lifecycle
Verification¶
Check Hot-Reload is Active¶
When you start the server with --reload, you'll see:
[Reload] Hot-reload enabled
[Reload] Watching: /home/user/capsule, /home/user/src/nauyaca
[Reload] Extensions: .py, .gmi
Test File Change Detection¶
-
Start the server with reload:
-
Edit a
.gmifile in./capsule: -
Check the logs - you should see:
Verify Backend¶
Check which backend is being used:
# With watchfiles installed:
[INFO] file_watcher_created: backend=watchfiles
# Without watchfiles (fallback):
[WARNING] watchfiles_not_available: fallback=polling hint=pip install watchfiles
Troubleshooting¶
Server Not Restarting on Changes¶
Problem: Files change but server doesn't restart.
Solutions:
-
Check the file extension is being watched:
-
Check the directory is being watched:
-
Check the logs for "changes_filtered" messages indicating files were ignored
Permission Errors¶
Problem: Permission denied errors when accessing files.
Solution: Ensure your user has read permissions on all watched directories:
Port Already in Use After Restart¶
Problem: "Address already in use" errors during restart.
Cause: Previous server didn't release the port in time.
Solution: This should resolve automatically after the 0.5s port release delay. If persistent:
- Reduce restart frequency by fixing errors before saving
- Check no other process is using port 1965:
Too Many Files Being Watched¶
Problem: High CPU usage or slow restarts.
Solution: Be more selective about watched directories:
# Instead of watching entire source tree:
nauyaca serve ./capsule --reload --reload-dir ./src
# Watch only specific subdirectories:
nauyaca serve ./capsule --reload --reload-dir ./src/nauyaca/server
Recursion Warning¶
Problem: "Detected reload recursion" in logs.
Cause: Server arguments include --reload flag, causing supervisor to spawn another supervisor.
Solution: This should never happen (Nauyaca filters reload flags automatically). If you see this:
- Check you're not setting
--reloadin a config file - Report as a bug
Advanced Configuration¶
Custom Polling Interval¶
The polling backend checks for changes every 1 second by default. This is not currently configurable via CLI but can be customized programmatically:
from pathlib import Path
from nauyaca.server.reload import ReloadConfig, run_with_reload
config = ReloadConfig(
watch_dirs=[Path("./capsule")],
watch_extensions=[".py", ".gmi"],
polling_interval=2.0 # Check every 2 seconds
)
run_with_reload(config, ["serve", "./capsule"])
Exclude Specific Files¶
Currently, hot-reload watches all files with matching extensions. To exclude files:
- Use a different extension for files you want ignored
- Move them outside watched directories
- Use
.gitignorestyle patterns (planned feature)
See Also¶
- Configure Server: Configure server settings that affect reload behavior
- Logging: Configure logging to track reload events
- CLI Reference: Complete CLI documentation including all reload flags
- Architecture: Learn about the server architecture