# 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.
[中文版本](README.zh.md)
## 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<Mutex>
- ✅ **Complete Error Handling**: Custom TimerError type with detailed error information
## Quick Start
Add to your `Cargo.toml`:
```toml
[dependencies]
ntp-timer = "0.1"
```
Basic usage:
```rust
use ntp_timer::{Config, TimerManager};
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create configuration
let config = Config::default()
.with_sync_interval(600) // Sync every 10 minutes
.with_jump_threshold(5); // Clock jump threshold: 5 seconds
// Initialize global timer
TimerManager::init_global_timer(Arc::new(config)).await?;
// Get current timestamp
let timestamp = TimerManager::get_timestamp()?;
println!("Current timestamp: {}", timestamp);
// Manual synchronization
let synced_ts = TimerManager::manual_sync().await?;
println!("Synced timestamp: {}", synced_ts);
Ok(())
}
```
## Configuration
| `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
| `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
```bash
# Run unit tests
cargo test --lib
# Run documentation tests
cargo test --doc
# Run all tests including integration tests
cargo test
```
## 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](README.zh.md).
---
**Made with ❤️ for reliable time synchronization in Rust**