sequence-generator-rust

64-bit IDs sequence generator based on the concepts outlined in Twitter Server's ID (formerly snowflake). Build on Rust

Table of Contents

Installation

sh git clone https://github.com/drconopoima/sequence-generator-rust.git cd sequence-generator-rust cargo build --release

The binary was generated under target/release/sequence-generator-rust

Description

You can generate sequential IDs based on timestamp, sequence number and node/worker ID (based on Twitter snowflake):

By default this package format defines:

Usage

Expected output would be like the following

sh $ cargo run \ 0: 344656800457424896

You can just as easily generate more than one ID from the CLI (-n|--number), as well as measure the time taken by the batch -d|--debug, providing a worker id of 0 (--node-id).

sh $ cargo run --release -- -n 8 --node-id 505 --debug \ 0: 344680846955905529 1: 344680846955906041 2: 344680846955906553 3: 344680846955907065 4: 344680846955907577 5: 344680846955908089 6: 344680846955908601 7: 344680846955909113 It took 611 nanoseconds

Each one of the parameters for the sequence are customizable.

By default the original Twitter snowflake format defines:

You can perfectly and easily recreate Twitter's snowflakes by passing the following command arguments.

sh $ cargo run --release -- -n 8 -d --unused-bits 1 --node-id-bits 10 --sequence-bits 12 --micros-ten-power 3 --custom-epoch '2010-11-04T01:42:54Z' --node-id 128 0: 137870923482005632 1: 137870923482006656 2: 137870923482007680 3: 137870923482008704 4: 137870923482009728 5: 137870923482010752 6: 137870923482011776 7: 137870923482012800 It took 571 nanoseconds

I wouldn't use Twitter's values nowadays. Hardware has advanced enough that with a single thread of a laptop average processor I'm generating each ID in ~60-70 nanoseconds, even when reaching close to the maximum sequence and stalling a bit waiting for the next millisecond, while the Twitter's defaults always generate the full sequence and then stalls for 55% of the time waiting (averaging 135-145ns per ID). Twitter's snowflakes are optimal if the hardware takes 245ns per ID or lower. Furthermore, having tenths of a millisecond precision means more accurate time & fast sorting if coupled with a Radix sort algorithm.

The specific structure of the integers at the binary level includes:

You can also customize by dotenv file. Copy the file .env-example into .env

sh cp .env-example .env

And change the example values to your liking.

The prevalence of the dotenv values is higher than CLI parameters passed.

The only supported custom epoch format is RFC-3339/ISO-8601 both as CLI argument and from the dotenv file.

Library

```rust use std::time::UNIXEPOCH; use ::sequencegenerator::*;

let customepoch = UNIXEPOCH; // SystemTime object representing custom epoch time. Use checkedadd(Duration) for different time let nodeidbits = 10; // 10-bit node/worker ID let sequencebits = 12; // 12-bit sequence let unusedbits = 1; // unused (sign) bits at the start of the ID. 1 or 0 generally let microstenpower = 3; // Operate in milliseconds (10^3 microseconds) let nodeid = 500; // Current worker/node ID let cooldown_ns = 1500; // initial time in nanoseconds for exponential backoff wait after sequence is exhausted

// Generate SequenceProperties let properties = sequencegenerator::SequenceProperties::new( customepoch, nodeidbits, nodeid, sequencebits, microstenpower, unusedbits, cooldownns, );

// Generate an ID let id = sequencegenerator::generateid(&mut properties).unwrap(); // Decode ID // Timestamp let timestampmicros = sequencegenerator::decodeidunixepochmicros(id, &properties); // Sequence let sequence = sequencegenerator::decodesequenceid(id, &properties); // Node ID let idnode = sequencegenerator::decodenode_id(id, &properties); ```

Support

Please open an issue for support.

Contributing

Please contribute using Github Flow. Create a branch, add commits, and open a pull request.