-
Notifications
You must be signed in to change notification settings - Fork 201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UUIDv6–v8 Support #523
Comments
Looks like I've got some reading to do 👀 These are basically ULIDs are they? |
I hadn't seen ULID before, but looking at the project it seems very similar, UUID has more variety in what kind of timestamp you can use. |
Today I ran across a project that collects all UUIDv6 prototypes. It lacks Rust implementation :) If you add UUIDv6 support to your library, it would be great https://github.com/uuid6/prototypes/
|
As I understand, UUIDv6 can be sorted and the sorted list would be in the generated time order that make UUIDv6 much more desirable for using as primary key or alike in databases |
Thanks @XAMPPRocky and @VladimirMarkelov. I'll spend some time unpicking the spec to see if it would make sense to share our |
Ok, based on a really quick reading it looks like our |
Do we have any experience so far from similar implementations on what a good ratio of subsecond precision / clock sequence / random data we should target for |
This will be great to have! |
Would it be possible to make it user-configurable? |
Hey @coreh 👋 Are you currently looking at using these new UUID variants? If so do you have any constraints or experiences to share? We could look at making this configuration for sure, but whether or not we do that unconditionally (in something like |
Yeah, I'm currently looking at using them for a hobby project (very early, in concept stage). My use case is to have a bunch of (untrusted and sandboxed) WASM applications running in a mesh network of hosts. Resources are identified by UUIDs, "owned" by the different applications, and are shared and accessible (via message passing) throughout the entire network. Applications can also be "migrated" between hosts. My idea is to use the the highest amount of bits possible from the I also suspect (but I'm not entirely sure) the big endian, lexicographical sorting aspect of UUIDv7 will help with compression over the wire, especially when serializing/deserializing resource state when applications are migrated between nodes. |
Ah I see 🤔 I was hoping we could use the same clock infrastructure we have for I saw the RFC got pushed back to next year. I don’t think I’ve ever looked at an IETF RFC that was in draft before so am not sure how normal that is 🙂 |
FWIW I've not been involved with IETF, but just from my experience implementing the RFCs, there's plenty of tech in production that lives in the draft or proposed RFC space for a long time, it more represents how much change there could be. For example; HTTP/2 (RFC 7540) and QUIC (RFC 9000) are still considered proposed standards by the IETF despite everyone using them. |
The new UUID formats are being discussed in this github repository: https://github.com/uuid6/uuid6-ietf-draft
|
Wow! Ok there you go.
Ah thanks @fabiolimace! 👀 I'll sketch this out on a branch and we can decide whether or not we want to ship them under a |
So we currently have access to 96bits of timestamp (64bits of timestamp and 32bits of nanos) Maybe something like: pub struct Precision(TimestampPrecision, SequencePrecision);
pub struct TimestampPrecision(u8);
impl TimestampPrecision {
pub const SECONDS: Self = Self(0);
pub const MILLIS: Self = Self(3);
..
pub fn from_places(places: u8) -> Self { .. }
}
pub struct SequencePrecision(u8);
impl SequencePrecision {
pub const V1: Self = Self(14);
pub fn from_bits(bits: u8) -> Self { .. }
}
pub trait ClockSequence {
fn precision(&self) -> Precision { Precision(TimestampPrecision::MILLIS, SequencePrecision::V1) }
fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16;
}
impl Uuid {
// Without precision we'll assume 96(?)bits of timestamp and node are for the timestamp
// This can produce some jittery results beyond the actual precision of the timestamp stored
fn to_timestamp_with_precision(&self, precision: Precision) -> Timestamp { .. }
}
impl Uuid {
// Any truncated portion of the timestamp to the end of the UUID will be filled with random data
// The precision used to generate the timestamp will determine when it truncates
pub fn new_v7(ts: Timestamp) -> Result<Self, crate::Error> { .. }
} The idea being we can do this without any breakage to What do you all think? |
I see the reference Python implementation has these defaults for
We could probably use the same. |
We're working towards a I think the sketch I made above is a bit unnecessary. All we really need is a way to retain all the precision in |
Is anyone working on this ? I could make a PR for |
Hi @malobre 👋 There isn't any active work on this right now. I haven't been following the RFC too closely, but was under the impression that things were changing in it so figured I'd check back in with it later. If you'd like to work on some v7 support we can work out how to ship it, either in |
I have forked this repo and started to play with things on the v7 branch. I will be putting any public facing additions behind the Working with It makes sense to share the struct between v1 & v6, but for v7 not so much. |
Maybe this is something to take into account |
Super excited to have uuid v7 support. @malobre does your fork currently work? |
No, I only made some groundwork as I intended to clarify some things beforehand. In the meantime, here's a snippet for single-node, non-batched, UUIDv7 generation: let uuid = {
use std::time::{SystemTime, UNIX_EPOCH};
let mut buf = rand::random::<u128>() & 0xFFF3FFFFFFFFFFFFFFF;
// 48 bits unix timestamp in ms
buf |= SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("SystemTime before UNIX Epoch")
.as_millis() << 80;
// version
buf |= 0x7 << 76;
// variant
buf |= 0b10 << 62;
uuid::Uuid::from_u128(buf)
}; Edit: I thought I should really emphasize that you should NOT use the above snippet if you intend to generate UUIDs in a distributed fashion or in batches. |
FYI, I stumbled upon a rust implementation: https://github.com/LiosK/uuid7-rs I believe the main challenge will be integrating UUIDv7 with the existing |
The |
Thanks for all the work you put in to this @rrichardson! 🙇 I'm glad the RFC moved away from the original variable-precision timestamp they had for v7 to a much simpler milliseconds-since-unix-epoch. I've papered over some of the issues with Before we release this, I would like to gate it behind our |
The first release on crates.io that supports v6-v8 UUIDs is published as |
I'll update the OP to include a link, but it looks like the working group responsible for the new UUID RFC is working here |
cc @KodrAus
[build]
rustflags = ["--cfg uuid_unstable"] Isn't there an alternative way to allow using those features other than manually setting this? |
@ConsoleTVs You can put [build]
rustflags = ["--cfg", "uuid_unstable"] As soon as we're confident that these new versions have a stable standard we'll be able to remove that required |
Ah, had tried it before but didn't work. What's the difference between those two? rustflags = ["--cfg uuid_unstable"]
rustflags = ["--cfg", "uuid_unstable"] |
I think |
Indeed the first one crashes. Interesting. Your solution works, thank you! |
Would anybody happen to know how we can the status of the current IETF RFC? From memory it had some deadline around March, but I'm not familiar with how their processes work. Would asking on their mailing list be an appropriate thing to do? |
@KodrAus between the issue tracker https://github.com/ietf-wg-uuidrev/rfc4122bis and the mailing list https://mailarchive.ietf.org/arch/browse/uuidrev/?q=draft-ietf-uuidrev-rfc4122bis it seems like they're just nitpicking the formatting and such. Maybe you could ping @kyzer-davis who seems to be heading it up. Since they're currently focusing on serious issues like this I'd have to imagine that the implementation details aren't going to change any further. Are you considering removing the |
@tgross35 As soon as the standard is fixed I'd love to get rid of the |
@KodrAus today the RFC maintainer posted some updates for the new recently released draft, I'm not sure if there's anything relevant there: uuid6/prototypes#42 Do you have any idea which version of the draft this crate supports? I'll submit a PR to the readme for that repo to add this to the implementations table, unless you prefer to DIY https://github.com/uuid6/prototypes |
@tgross35 Thanks for checking in to this. I think we based our implementation off the final version of the draft before its scope widened to rewriting RFC 4122 🤔 We should keep up-to-date with whatever the current version is though. If you'd like to submit a PR that adds |
Thanks @tgross35 for following up on things! 🙇 This is where things are at right now. It seems like we're getting close to having these new formats stabilized in more or less their current form. |
Any progress on the stabilization of UUID v6-v8? |
@photino i think there will be a few more months before the RFC becomes officially accepted. Close, but not there yet - status at https://mailarchive.ietf.org/arch/browse/uuidrev/?q=draft-ietf-uuidrev-rfc4122bis |
The RFC status has become |
I think the test vectors (appendix A) changed for one of the new versions at some point. I'm not sure if related tests exist in this repo, but maybe they are worth pulling in? I'm not sure where benchmarks are used, but one for v7 would be interesting to see how it compares to v4 |
Oh well spotted. It looks like the |
In my stabilization PR I added a benchmark you can run to evaluate the impact of switching from
|
It looks correct to my eyes. But maybe it would be good to just add a test with the exact v6 and v7 examples from the RFC as a sanity check?
🤦 I was thinking the existing benchmark was for v1 and not v4, couldn't figure out why the difference was so large. Thanks for the results! |
Is your feature request related to a problem? Please describe.
There is a new draft RFC for UUID formats that are more database friendly, it would be nice if these were supported in the
uuid
crate, since the new formats share a lot of the same internals.Describe the solution you'd like
An implementation of UUIDv6, v7, and v8 from the IETF RFC.
Is it blocking?
No, it would just be cool to have.
EDIT (@KodrAus): The RFC is being worked on here
The text was updated successfully, but these errors were encountered: