Skip to content

lispking/globuid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GlobUid

A globally unique ID generator with pluggable algorithms and transport layer, written in Rust.

Crates.io Documentation License: Apache 2.0 build status Ask DeepWiki

Features

  • Multiple ID Algorithms: Snowflake, ULID, NanoID
  • Pluggable Storage: Memory, File, or implement your own
  • Optional Transport Layer: HTTP REST API or gRPC
  • High Performance: Async/await with Tokio runtime
  • Distributed Support: Worker ID support for Snowflake algorithm
  • Zero Dependencies Core: Use as a library without HTTP/gRPC overhead

Algorithms Comparison

Algorithm Output Length Sortable Distributed Use Case
Snowflake u64 64-bit Time-sortable ✓ (1024 nodes) Distributed systems, databases
ULID String 26 chars Lexicographically URLs, distributed databases
NanoID String Configurable Short URLs, session IDs

Snowflake

64-bit unique ID with the following structure:

| 1 bit sign | 41 bits timestamp | 10 bits worker_id | 12 bits sequence |
  • 41 bits timestamp: ~69 years from custom epoch
  • 10 bits worker_id: 1024 nodes maximum
  • 12 bits sequence: 4096 IDs per millisecond per node

ULID

Universally Unique Lexicographically Sortable Identifier:

| 48 bits timestamp | 80 bits randomness |
  • 26 characters, Base32 encoded
  • Case-insensitive
  • URL-safe
  • Monotonic increment support

NanoID

URL-friendly unique string identifier:

  • Default: 21 characters
  • Customizable length and alphabet
  • URL-safe characters: A-Za-z0-9_-

Installation

Add to your Cargo.toml:

[dependencies]
globuid = "0.1.0"

# With HTTP support
globuid = { version = "0.1.0", features = ["http"] }

# With gRPC support
globuid = { version = "0.1.0", features = ["grpc"] }

# With all features
globuid = { version = "0.1.0", features = ["full"] }

Usage

As a Library

Snowflake (Distributed Systems)

use globuid::{Snowflake, SnowflakeConfig, MemoryStorage, IdGenerator};
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let config = SnowflakeConfig {
        worker_id: 1,  // Unique worker ID (0-1023)
        ..Default::default()
    };
    
    let storage = Arc::new(MemoryStorage::new());
    let generator = Snowflake::new(config, storage).await.unwrap();
    
    // Generate single ID
    let id = generator.generate().await.unwrap();
    println!("ID: {}", id);
    
    // Generate batch
    let ids = generator.generate_batch(10).await.unwrap();
    for id in ids {
        println!("ID: {}", id);
    }
}

ULID (Lexicographically Sortable)

use globuid::{Ulid, IdGenerator};

#[tokio::main]
async fn main() {
    let generator = Ulid::with_default();
    
    let id = generator.generate().await.unwrap();
    println!("ULID: {}", id);  // e.g., "01ARZ3NDEKTSV4RRFFQ69G5FAV"
}

NanoID (Short URLs)

use globuid::{NanoId, NanoIdConfig, IdGenerator};

#[tokio::main]
async fn main() {
    // Default: 21 characters
    let generator = NanoId::with_default();
    let id = generator.generate().await.unwrap();
    println!("NanoID: {}", id);  // e.g., "V1StGXR8_Z5jdHi6B-myT"
    
    // Custom length
    let config = NanoIdConfig::new().length(10);
    let short_generator = NanoId::new(config);
    let id = short_generator.generate().await.unwrap();
    println!("Short ID: {}", id);  // e.g., "IRFa-VaH2b"
}

As a Server

HTTP REST API

# Start HTTP server with Snowflake
cargo run --features http -- --algorithm snowflake --port 8080

# With ULID
cargo run --features http -- --algorithm ulid --port 8080

# With NanoID (custom length)
cargo run --features http -- --algorithm nanoid --nanoid-length 10 --port 8080

API Endpoints:

Method Endpoint Description
GET /health Health check
GET /id Generate single ID
GET /id/batch?count=N Generate N IDs (max 10000)

Example:

# Health check
curl http://localhost:8080/health
# {"status":"ok"}

# Single ID
curl http://localhost:8080/id
# {"id":"287628074806149120"}

# Batch IDs
curl "http://localhost:8080/id/batch?count=5"
# {"ids":["...","..."],"count":5}

gRPC

# Start gRPC server
cargo run --features grpc -- --algorithm ulid --protocol grpc --port 9090

Proto Definition:

service GlobUid {
    rpc Generate(GenerateRequest) returns (GenerateResponse);
    rpc GenerateBatch(GenerateBatchRequest) returns (GenerateBatchResponse);
    rpc Health(HealthRequest) returns (HealthResponse);
}

Storage Backends

Memory Storage (Default)

Non-persistent in-memory storage. Suitable for single-instance deployments.

use globuid::MemoryStorage;
use std::sync::Arc;

let storage = Arc::new(MemoryStorage::new());

File Storage

Persistent file-based storage. Survives application restarts.

use globuid::FileStorage;
use std::sync::Arc;

let storage = Arc::new(FileStorage::new("/path/to/state.json"));

Custom Storage

Implement the Storage trait for custom backends (Redis, PostgreSQL, etc.):

use globuid::{Storage, GeneratorState};
use std::pin::Pin;
use std::future::Future;

struct RedisStorage { /* ... */ }

impl Storage for RedisStorage {
    fn load(&self) -> Pin<Box<dyn Future<Output = Result<GeneratorState, Box<dyn std::error::Error + Send + Sync>>> + Send + '_>> {
        // Load state from Redis
    }
    
    fn save(&self, state: GeneratorState) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn std::error::Error + Send + Sync>>> + Send + '_>> {
        // Save state to Redis
    }
}

CLI Options

GlobUid - Global Unique ID Service

Usage: globuid [OPTIONS]

Options:
  -a, --algorithm <ALGORITHM>  ID algorithm: "snowflake", "ulid", "nanoid" [default: snowflake]
  -w, --worker-id <WORKER_ID>  Worker ID (0-1023) for Snowflake [default: 0]
  -p, --port <PORT>            Port to listen on [default: 8080]
      --host <HOST>            Host to bind to [default: 0.0.0.0]
  -s, --storage <STORAGE>      Storage backend: "memory" or "file" [default: memory]
      --storage-path <PATH>    File path for file storage
  -P, --protocol <PROTOCOL>    Protocol: "http" or "grpc" [default: http]
      --nanoid-length <LEN>    ID length for NanoID [default: 21]
  -h, --help                   Print help
  -V, --version                Print version

Feature Flags

Feature Description
http Enable HTTP REST API server
grpc Enable gRPC server
full Enable all transport layers

Performance

Benchmarks on Apple M1 (single thread):

Algorithm Ops/sec
Snowflake ~2M/sec
ULID ~1.5M/sec
NanoID (21 chars) ~800K/sec

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

A globally unique ID generator with pluggable algorithms and transport layer, written in Rust.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors