NTP Timer
⏱️ A lightweight NTP time synchronization library for Rust applications.
Provides in-process cached global time with automatic background synchronization and clock-jump detection. Perfect for services that need reliable time without depending on system clock.
Features
- ✅ NTP Time Synchronization: Fetch precise timestamps from multiple NTP servers
- ✅ In-Memory Cache: <0.1ms fast local calculation
- ✅ Clock Jump Detection: Automatically detect and handle system clock adjustments
- ✅ Background Synchronization: Async periodic sync tasks that don't block the main thread
- ✅ Fully Configurable: All critical parameters are customizable (sync interval, jump threshold, etc.)
- ✅ Thread-Safe: Concurrent access supported via Arc
- ✅ Complete Error Handling: Custom TimerError type with detailed error information
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
Basic usage:
use ;
use Arc;
async
Configuration
| Parameter | Default | Description |
|---|---|---|
sync_interval_secs |
600 | Background sync interval (seconds) |
clock_jump_threshold_secs |
5 | Clock jump detection threshold (seconds) |
ntp_servers |
[ntp.ntsc.ac.cn, ...] |
List of NTP servers |
max_retries |
3 | Maximum retry attempts |
socket_timeout_secs |
5 | Socket timeout (seconds) |
API Reference
TimerManager::init_global_timer(config)
Initializes the global timer. On first call, fetches timestamp from NTP servers and starts background sync task.
Returns: Result<(), TimerError>
TimerManager::get_timestamp()
Gets the current timestamp via fast local path (<0.1ms).
Returns: Result<i64, TimerError>
TimerManager::manual_sync()
Manually triggers NTP synchronization and returns the latest timestamp.
Returns: Result<i64, TimerError>
Architecture
TimerManager (Public API)
├── GlobalTimer (Core Data Structure)
│ ├── base_timestamp (NTP initial timestamp)
│ ├── base_instant (System clock reference point)
│ └── last_sync_at (Last sync time)
├── Config (Configurable Parameters)
└── NTP Module (NTP Protocol Implementation)
Design Highlights
Fast Path
get_timestamp() completes <0.1ms in 99.9% of cases:
= base_timestamp + (Instant::now() - base_instant).as_secs()
Clock Jump Detection
Checked during each sync:
|new_ntp_timestamp - current_estimate| > threshold
- Exceeds threshold → Reinitialize timer
- Otherwise → Smooth baseline update (drift correction)
Background Synchronization
Async task runs every sync_interval_secs:
- Non-blocking main thread
- Continues using local timer on failure
- Automatically detects and recovers from clock jumps
Performance Metrics
| Operation | Duration | Notes |
|---|---|---|
get_timestamp() |
<0.1ms | Fast path (pure local calculation) |
init_global_timer() |
50-100ms | Initial setup (NTP request) |
manual_sync() |
50-100ms | Manual sync (NTP request) |
| NTP sync frequency | 1/10min | Background task interval |
Testing
# Run unit tests
# Run documentation tests
# Run all tests including integration tests
Use Cases
- Distributed systems requiring synchronized timestamps
- Rate limiting and traffic shaping (time-window based)
- Cache expiration management
- Log aggregation and correlation
- Scheduled task execution
- Any application needing reliable time without system clock dependency
Limitations
- Precision: Returns time in seconds (not sub-millisecond precision)
- Scope: Single application process (not system-wide)
- Dependencies: Requires async runtime (tokio)
Future Plans
- Millisecond/microsecond precision support
- Configurable NTP server lists
- Support for alternative time sources (PTP, Roughtime)
- Performance benchmarks and optimizations
License
MIT
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
For Chinese contributors, see README.zh.md.
Made with ❤️ for reliable time synchronization in Rust