Closed kyzer-davis closed 1 year ago
@kyzer-davis I'll take a crack at this. A lot of these should be simple. In some cases non-normative language can be used as you suggest, and this includes some situations where just a general concept is being described and the word "should" is used but then has been capitalized - I don't think we need that. Even the RFC describing "SHOULD" https://www.rfc-editor.org/rfc/rfc2119 also uses "should" in a non-normative way in its introduction, I think we can take a cue from that. In other scenarios the "SHOULD" can just be removed altogether with some simple rewording.
Here's my proposal on it:
Implementations SHOULD use the current timestamp from a reliable source to provide values that are time-ordered and continually increasing.
Implementations MUST use the current timestamp from a reliable source to provide values that are time-ordered and continually increasing.
- Agreed, upgrade to MUST.
Care SHOULD be taken to ensure that timestamp changes from the environment or operating system are handled in a way that is consistent with implementation requirements.
Take care to ensure that timestamp changes from the environment or operating system are handled in a way that is consistent with implementation requirements.
- Suggest using non-normative language, recommendation is not specific enough, just general advice.
For other levels of precision UUIDv8 SHOULD be utilized.
For other levels of precision UUIDv8 is available as an option.
- Suggest using non-normative language, the spec gives all available UUIDs, the reader can already choose for themselves, I don't see a need to be more specific.
Care SHOULD be given to ensure that the proper length is selected for a given timestamp.
Take care to ensure that the proper length is selected for a given timestamp.
- Agree with earlier suggestion, non-normative language seems good.
If a system overruns the generator by requesting too many UUIDs within a single system time interval, the UUID service SHOULD either return an error, or stall the UUID generator until the system clock catches up, and MUST NOT return knowingly duplicate values.
If a system overruns the generator by requesting too many UUIDs within a single system time interval, the UUID service MUST NOT return knowingly duplicate values, and instead can either return an error, or stall the UUID generator until the system clock catches up.
- I think the MUST NOT provides the most important imperative here. I don't like the idea of saying the stall or error is what they must do because what if there's some other solution we haven't thought of? The point is that it shouldn't return duplicates, so I think we just say that.
Care SHOULD be taken to ensure UUIDs generated in batches are also monotonic.
Take care to ensure UUIDs generated in batches are also monotonic.
- Agree with suggestion, go non-normative
That is, if one thousand UUIDs are generated for the same timestamp, there SHOULD be sufficient logic for organizing the creation order of those one thousand UUIDs.
That is, if one thousand UUIDs are generated for the same timestamp, there should be sufficient logic for organizing the creation order of those one thousand UUIDs.
- This is not a specific requirement, it's simply giving an example of correct behavior, I think "should" is okay here. Or if someone disagrees let's just reword so it's non-normative and not use "should" or "SHOULD".
Batch UUID creation implementations MAY utilize a monotonic counter that SHOULD increment for each UUID created during a given timestamp.
Batch UUID creation implementations MAY utilize a monotonic counter that increments for each UUID created during a given timestamp.
- Reword to non-normative
A fixed bit-length counter, if present, SHOULD be positioned immediately after the embedded timestamp.
A fixed bit-length counter, if present, MUST be positioned immediately after the embedded timestamp.
- Agreed per above, becomes MUST
With this method, the rand_a section of UUIDv7 SHOULD be used as fixed-length dedicated counter bits that are incremented by one for every UUID generation.
With this method, the rand_a section of UUIDv7 MUST be used as fixed-length dedicated counter bits that are incremented for every UUID generation.
- Could also leave as SHOULD but this works too - we say it gets incremented but not by how much.
The increment value for every UUID generation SHOULD be a random integer of any desired length larger than zero.
The increment value for every UUID generation is a random integer of any desired length larger than zero.
- What if we just say "is", since we're describing a method of doing something, I think that works.
Implementations utilizing the fixed-length counter method SHOULD randomly initialize the counter with each new timestamp tick.
Implementations utilizing the fixed-length counter method randomly initialize the counter with each new timestamp tick.
- Same deal here, we're explaining how to do something, we've already set up the context for it, the normative language doesn't help us here, can just come out.
However, when the timestamp has not incremented, the counter SHOULD be frozen and incremented via the desired increment logic.
However, when the timestamp has not incremented, the counter is frozen and incremented via the desired increment logic.
- Ditto
Care SHOULD also be given to ensure that the counter length selected leaves room for sufficient entropy in the random portion of the UUID after the counter.
Take care to ensure that the counter length selected leaves room for sufficient entropy in the random portion of the UUID after the counter.
- how about that
Counter rollovers SHOULD be handled by the application to avoid sorting issues.
Counter rollovers MUST be handled by the application to avoid sorting issues.
- Agreed, upgrade to a MUST.
The general guidance is that applications that care about absolute monotonicity and sortability SHOULD freeze the counter and wait for the timestamp to advance which ensures monotonicity is not broken.
Implementations SHOULD check if the currently generated UUID is greater than the previously generated UUID
Applications SHOULD embed sufficient logic to catch these scenarios and correct the problem to ensure that the next UUID generated is greater than the previous, or at least report an appropriate error
And then everything else from 6.3. UUID Generator States and down in the earlier post I agree with the recommendation given and I think unless someone else expresses concerns, just go for it on those changes.
Generally, I agree with @bradleypeabody; rewording to non-normative verbiage should work very well in many contexts.
Some comments:
- Implementations SHOULD use the current timestamp from a reliable source to provide values that are time-ordered and continually increasing.
I think we should keep SHOULD here. MUST conflicts with the following "Altering, Fuzzing, or Smearing" section. Plus, I got a feature request to my prototype to add a feature to create a UUIDv7 with an arbitrary timestamp to migrate old IDs to UUIDv7 based on the created_at
database field. I think that's a legitimate use case.
- If a system overruns the generator by requesting too many UUIDs within a single system time interval, the UUID service SHOULD either return an error, or stall the UUID generator until the system clock catches up, and MUST NOT return knowingly duplicate values.
I would rather suggest to downgrade MUST NOT to SHOULD NOT here. With MUST, every compliant service on a machine MUST refuse to return a value when the system clock stops or goes backwards, which might cause the entire break down of applications running on that server, even if the absolute monotonicity is not a requirement of such applications. A generator should have an option to reset the state and continue when the system clock seems to be broken.
6.2. Monotonicity and Counters
- That is, if one thousand UUIDs are generated for the same timestamp, there SHOULD be sufficient logic for organizing the creation order of those one thousand UUIDs.
SHOULD sounds fine here. MUST sounds like prohibiting the generation of one thousand UUIDs without a monotonic counter. For some applications, it should absolutely be fine to get 1000 unordered UUIDs from a simple, much-easier-to-implement counter-less UUIDv7 generator.
- Batch UUID creation implementations MAY utilize a monotonic counter that SHOULD increment for each UUID created during a given timestamp.
MUST might be fine, but also we can simply omit SHOULD here.
- With this method, the rand_a section of UUIDv7 SHOULD be used as fixed-length dedicated counter bits that are incremented by one for every UUID generation.
Could be MUST if we would prohibit a counter shorter than 12 bits. Alternatively, we can reword this sentence not to mention rand_a
. The RFC already provides guidance of 12 to 42 bits for counters. That should be sufficient.
- Care SHOULD be taken to ensure the CSPRNG state is properly reseeded upon state changes, such as process forks, to ensure proper CSPRNG operation.
MUST is ideal, but note that in some environments it is very difficult or often impossible to reseed CSPRNG upon fork. We should perhaps keep SHOULD.
@kyzer-davis Here's a PR for this https://github.com/ietf-wg-uuidrev/rfc4122bis/pull/119. @LiosK I think I've addressed your concerns as well.
Will review tomorrow. Re-submission to IETF does not re-open until 7-22 anyway because of IETF 117.
Murray Feedback:
RFC2119
Question to answer for each:
6.1. Timestamp Considerations
6.2. Monotonicity and Counters
6.3. UUID Generator States
6.4. Distributed UUID Generation
6.5. Name-Based UUID Generation
6.6. Collision Resistance
6.8. Unguessability
6.9. UUIDs That Do Not Identify the Host
6.10. Sorting
6.11. Opacity
6.12. DBMS and Database Considerations