ntp-timer 0.1.0

A lightweight NTP time synchronization library for Rust applications. Provides in-process cached global time with background sync and clock-jump detection.
Documentation

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:

[dependencies]
ntp-timer = "0.1"

Basic usage:

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

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
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.


Made with ❤️ for reliable time synchronization in Rust