Skip to content

uuid v7#681

Merged
broofa merged 23 commits intouuidjs:mainfrom
pmccarren:uuid7
Jun 3, 2024
Merged

uuid v7#681
broofa merged 23 commits intouuidjs:mainfrom
pmccarren:uuid7

Conversation

@pmccarren
Copy link
Copy Markdown
Contributor

@pmccarren pmccarren commented Jan 22, 2023

UUID V7

This PR implements UUID V7, closing ref #580

V7 is implemented, tested and documented and ready for review! No changes to the other versions were made.

Relevant RFC documents:

Benchmarks

V7 appears as fast as V4 when not using native crypto.randomUUID generation.

Results:

Starting. Tests take ~1 minute to run ...
uuid.stringify() x 1,450,855 ops/sec ±2.12% (88 runs sampled)
uuid.parse() x 2,350,677 ops/sec ±1.19% (88 runs sampled)
---

uuid.v1() x 3,585,680 ops/sec ±0.86% (92 runs sampled)
uuid.v1() fill existing array x 9,229,031 ops/sec ±0.50% (93 runs sampled)
uuid.v4() x 13,834,376 ops/sec ±3.34% (84 runs sampled)
uuid.v4() fill existing array x 3,833,619 ops/sec ±1.51% (84 runs sampled)
uuid.v4() without native generation x 2,395,572 ops/sec ±1.27% (91 runs sampled)
uuid.v3() x 268,797 ops/sec ±1.32% (86 runs sampled)
uuid.v5() x 287,899 ops/sec ±1.12% (92 runs sampled)
uuid.v7() x 2,764,344 ops/sec ±0.95% (93 runs sampled)
uuid.v7() fill existing array x 2,801,443 ops/sec ±5.48% (84 runs sampled)
uuid.v7() with defined time x 3,223,107 ops/sec ±1.14% (89 runs sampled)
Fastest is uuid.v4()

TODO:

Copy link
Copy Markdown
Member

@broofa broofa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution @pmccarren ccarren. This looks promising!

In addition to the inline comments, can you add a unit test alongside https://github.com/uuidjs/uuid/blob/main/test/unit/v1.test.js, with similar assertions. Specifically, I'd like to see similar tests for sort order, uniqueness, and options handling. (And anything else you think may be relevant.)

The sorting will be of particular interest, since producing UUIDS that sort the same whether sorted by timestamp or lexicographically was pretty much the whole point of version 7. 😄

Note: This should not close #580, as the new RFC adds v6 and v8 formats, too, as well as the MAX_UUID constant. v7 is definitely the majority of what's needed, but we'll want to keep 580 open until we fill in the remaining items.

Lastly, the new RFC is still making it's way through the review process. I don't expect substantive changes at this point, so this is an appropriate time to be adding this. But as I noted in 580, I think it's prudent to go with an experimental version release tag of some sort.

@ctavan: Thoughts on how best to accept this? Should we create a v9-experimental branch that we merge this into rather than master? Then publish experimental releases from that?

@pmccarren
Copy link
Copy Markdown
Contributor Author

@broofa - glad to lend a hand! I appreciate your time reviewing the implementation.

This PR has been updated with your suggested changes, most notably:

  • reworked buffer management so rnds is not mutated
  • added v7 unit test coverage
  • fixed README generation (via npm run docs)

In regards to sorting, I've been considering a few different approaches and while not presently implemented in this PR, I absolutely agree it should be :) I'll work on implementing this as well the associated unit tests.

Copy link
Copy Markdown
Member

@LinusU LinusU left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good 👍

Lastly, the new RFC is still making it's way through the review process.

Thoughts on how best to accept this? Should we create a v9-experimental branch that we merge this into rather than master? Then publish experimental releases from that?

Personally think that we should keep this PR open until the spec has been ratified. If we merge into a v9 branch that would stop us from making a v9 release until that has happened, and that might potentially be a long time?

I think that it would be nice to backport the "version 2 is valid" bugfix right away to the current release though?

@ctavan
Copy link
Copy Markdown
Member

ctavan commented Jan 25, 2023

Thanks an lot for the contribution!

I initially thought this new feature could land in the v9 release, but given we’re broadening the validation regex it’s a breaking change and we’ll have to bump the major version.

I think it would be nice to somehow release it as a prerelease so that people have a chance to try it and provide feedback, but I think our current release and branching process is not yet ready for multiple active major releases. If anyone’s willing to take a look at this I’m happy to support (we were considering better automation for this for a while… #636).

I agree however, that we should not release this in a public major release until the draft has been accepted.

@broofa broofa changed the base branch from main to rfc4122bis January 25, 2023 23:46
@broofa
Copy link
Copy Markdown
Member

broofa commented Jan 25, 2023

Note: I've just created the rfc4122bis branch off main as a place to land this (and set it as the target for this PR). As @ctavan says, we haven't worked through the deploy & publish pipeline for non-main branches yet, so we'll have to figure that out.

Wish I could give you an ETA for that, but it's not been a priority for either of us. As he says... "Help Wanted".

Co-authored-by: Linus Unnebäck <linus@folkdatorn.se>
@broofa broofa added the bis label Feb 4, 2023
Copy link
Copy Markdown
Member

@broofa broofa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ctavan @LinusU Any other comments? If not, I'd like to get this merged (pending @pmccarren commiting his suggested change for the regex to allow 1-8).

Regarding the plan for the rfc4122bis branch, I've created a project to capture the remaining work, with brief notes on possible implementation details.

Honestly, there's not all that much left... if anyone is feeling inspired. ;-)

Lastly, thoughts on inviting Patrick to join the UUIDJS org? He's done some solid work here that's much appreciated, and seappears to have good street cred. If people could weigh in on that idea (including you, Patrick), we can move forward or not as appropriate. [cc'ing @TrySound here]

@pmccarren
Copy link
Copy Markdown
Contributor Author

@broofa just merged the 1-8 regex update. I'm close to done with implementing monotonic generation - I'd prefer to merge once that's wrapped. Will be buttoned up in a day or two.

As for UUIDJS Org, I'll let my work speak for itself but will add that if you'll have me I'll be an active participant :)

@pmccarren
Copy link
Copy Markdown
Contributor Author

@broofa I just finished adding monotonic support, and it's ready for review! Took a bit of finesse but I'm rather happy with how it turned out. In addition to the monotonicity related unit tests, I manually tested sorting preservation during generation of 100M uuids.

couple of sequence counter implementation notes:

  • when additional generations occur inside the same millisecond, we use a dedicated 31 bits as an incrementing sequence counter. Referred to as Fixed-Length Dedicated Counter Bits (Method 1) in the draft RFC.
  • seq is 31 bits and (re)initialized from the random data pool whenever the clock advances/changes. as the seq is initialized randomly, for nominal usage there is a significant amount (74 bits) of randomness in a given v7 uuid.
  • when the sequence counter rolls over we increment the internal date by 1 millisecond and continue. this accepts the tradeoff of minor clock drift for lexicographical sorting in substantial batch id generation workloads.
  • if the internal date ever exceeds 10 seconds beyond system time, both the date and seq are hard reset.
  • lexicographical sorting is preserved up to (2^31)*10000 generations for a provided millisecond.
  • the seq is stored as 31 bits. the 12 high bits and 19 low bits are stored separately in the uuid to preserve sorting while maintaining a large enough counter size

Pending review, I believe this PR is ready to go now!

@pmccarren pmccarren requested a review from broofa February 9, 2023 23:19
@mbrimmer83
Copy link
Copy Markdown

Rumor has it uuid v7 is now part of the proposed standard What would it take to get this over the finish line?

@ryan-keswick
Copy link
Copy Markdown

Any updates on this?

@broofa broofa changed the base branch from rfc4122bis to main June 3, 2024 00:10
@broofa broofa removed the bis label Jun 3, 2024
@broofa broofa mentioned this pull request Jun 3, 2024
9 tasks
@broofa
Copy link
Copy Markdown
Member

broofa commented Jun 3, 2024

Did another review pass. Pushed a couple minor documentation tweaks to update things now that RFC9562 is official.

@ctavan: In the interests of moving forward with 9562, I'm merging this. If there are questions or concerns, we can address those in followup PRs.

@pmccarren: Thanks for the great work on this. My apologies for letting this stagnate for so long. Now that 9562 is official, my goal is to get this pushed out ASAP.

@broofa broofa merged commit db76a12 into uuidjs:main Jun 3, 2024
@ctavan
Copy link
Copy Markdown
Member

ctavan commented Jun 3, 2024

I‘m all for it, thanks for taking care!

But let’s make use of the conventional commit message format in the squash commits so we get proper autogenerated changelogs.

@broofa
Copy link
Copy Markdown
Member

broofa commented Jun 3, 2024

let’s make use of the conventional commit message format in the squash commits

Ugh... I keep screwing that up. :-(

@ctavan
Copy link
Copy Markdown
Member

ctavan commented Jun 3, 2024

Does GitHub have an option to run actions (commitlint) before squash merges?

@broofa
Copy link
Copy Markdown
Member

broofa commented Jun 3, 2024

There's probably a way, but... 🤷

@pmccarren
Copy link
Copy Markdown
Contributor Author

@broofa and @ctavan I appreciate your time in reviewing and assisting with the PR. I'm excited we're collectively one step closer to uuid7 being widely available :)

If there is a need for assistance, I have time I can dedicate towards experimental deploys. Just let me know if it'll be helpful, and I'm happy to dive in.

@broofa
Copy link
Copy Markdown
Member

broofa commented Jun 3, 2024

@pmccarren That'd be awesome. On the deploy front, there's two nuts we'd like to crack:

  1. Enforce Conventional Commits™ on every commit that goes onto the main branch. (witness my fumbling the message on this PR)
  2. Automate the deploy process so we're not manually publishing from our laptops.

We haven't tackled the former yet, but if you know a way to do that, we're all for it.

For the latter, I put up #725 a couple years ago before getting distracted by other things. The main goal there was to get away from our current ad-hoc release process that has us creating PRs just to update package.json#version, and running standard-version and npm publish manually on our laptops. Specifically, I wanted to automate the following:

  • Update CHANGELOG with notes for all relevant changes
  • Bump package.json#version based on Conventional Commit message semantics
  • Create git tag for release
  • Run npm publish in a workflow

release-please is (I think) still a good choice for that but I haven't followed development of that project so I'm not sure what bells-and-whistles may have been added. If you can get that working, that'd be great. Or if there's another option you think would work better I'm open to suggestions.

I've sent you an invite to the uuidjs org here. Let me know if there are permissions you need here or on NPM for this work. (Obviously we'll need to be careful about what gets npm-published.)

And thank you for stepping up to help (again).

@sachinjnd
Copy link
Copy Markdown

@broofa / @pmccarren Now that the changes for uuid v7 are merged, what's the plan for release on npm?

@ctavan
Copy link
Copy Markdown
Member

ctavan commented Jun 8, 2024

See #760

gisbdzhch pushed a commit to gisktzh/gb3-web_ui that referenced this pull request Jun 19, 2024
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [uuid](https://github.com/uuidjs/uuid) | dependencies | major | [`^9.0.0` -> `^10.0.0`](https://renovatebot.com/diffs/npm/uuid/9.0.1/10.0.0) |

---

### Release Notes

<details>
<summary>uuidjs/uuid (uuid)</summary>

### [`v10.0.0`](https://github.com/uuidjs/uuid/blob/HEAD/CHANGELOG.md#1000-2024-06-07)

[Compare Source](uuidjs/uuid@v9.0.1...v10.0.0)

##### ⚠ BREAKING CHANGES

-   update node support (drop node@12, node@14, add node@20) ([#&#8203;750](uuidjs/uuid#750))

##### Features

-   support support rfc9562 MAX uuid (new in RFC9562) ([#&#8203;714](uuidjs/uuid#714)) ([0385cd3](uuidjs/uuid@0385cd3))
-   support rfc9562 v6 uuids ([#&#8203;754](uuidjs/uuid#754)) ([c4ed13e](uuidjs/uuid@c4ed13e))
-   support rfc9562 v7 uuids ([#&#8203;681](uuidjs/uuid#681)) ([db76a12](uuidjs/uuid@db76a12))
-   update node support matrix (only support node 16-20) ([#&#8203;750](uuidjs/uuid#750)) ([883b163](uuidjs/uuid@883b163))
-   support rfc9562 v8 uuids ([#&#8203;759](uuidjs/uuid#759)) ([35a5342](uuidjs/uuid@35a5342))

##### Bug Fixes

-   revert "perf: remove superfluous call to toLowerCase ([#&#8203;677](uuidjs/uuid#677))" ([#&#8203;738](uuidjs/uuid#738)) ([e267b90](uuidjs/uuid@e267b90))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or rename PR to start with "rebase!".

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.