64-bit IDs sequence generator based on the concepts outlined in Twitter Server's ID (formerly snowflake). Build on Rust
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
You can generate sequential IDs based on timestamp, sequence number and node/worker ID (based on Twitter snowflake):
By default this package format defines:
Generate a single sequence number as follows, with a worker-id set up from .env
file (default 0):
sh
$ cargo run \
0: 731587959438966784
Generate many sequence values (-n|--number
), provide a custom worker id (--node-id
), and measure the time taken (-d|--debug
):
sh
cargo run --release -- -n 8 --node-id 505 --debug
text
0: 731586108621586937
1: 731586108621587449
2: 731586108621587961
3: 731586108621588473
4: 731586108621588985
5: 731586108621589497
6: 731586108621590009
7: 731586108621590521
It took 661 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
The specific structure of the integers at the binary level includes:
44 bits
and sampling every 100 mcs
, equivalent to argument --micros-ten-power 2
). You cannot customize number of bits of the timestamp directly, but by indirectly setting different values for other bit groups.11 bits
)9 bits
)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 precedence of parameters assigned through the command-line launch arguments is the highest, whichever are not assigned can be retrieved by use of a .env
file, and if still unassigned parameters remains, then default values described above are used.
The only supported custom epoch format is RFC-3339/ISO-8601
both as CLI argument and from the dotenv file.
Check a detailed analysis for a generated value in the auxiliar bit structure analysis
See auxiliar benchmarking notes
```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); ```
Please open an issue for support.
See changelog
Please contribute using Github Flow. Create a branch, add commits, and open a pull request.