Closed CMCDragonkai closed 3 years ago
Thank you for raising this concern!
I think the monotonic seq
counter helps avoiding collisions as shown – when a timestamp matches the previous one, the clock sequence is increased by 1, otherwise it gets reset to 0: https://github.com/kripod/uuidv7/blob/501d4ef5f97893e445c4160541971741db9f9257/src/_common.ts#L12-L18
OS clock drifts may possibly happen, but is there a sufficient alternative for Date.now()
in JS to avoid those? We may use performance.timing.navigationStart + performance.now()
or something similar:
unlike
Date.now()
, the values returned byperformance.now()
always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP)
There are definitely solutions we could hack into the code itself. But I'm requesting for some flexibility. If as a user I can inject my own clock source, I can work out a solution in my specific environment. If I don't inject a clock source, I'm happy for the library to default it to whatever is convenient.(
So if Date.now()
is being used, I suppose an object that has the now
method should be sufficient. Then the default implementation is Date
.
A typescript interface can enforce this.
On 9/28/21 4:34 PM, Kristóf Poduszló wrote:
Thank you for raising this concern!
I think the monotonic |seq| counter helps avoiding collisions as shown – when a timestamp matches the previous one, the clock sequence is increased by 1, otherwise it’s reset to 0: https://github.com/kripod/uuidv7/blob/501d4ef5f97893e445c4160541971741db9f9257/src/_common.ts#L12-L18 https://github.com/kripod/uuidv7/blob/501d4ef5f97893e445c4160541971741db9f9257/src/_common.ts#L12-L18
OS clock drifts may possibly happen, but is there a sufficient alternative for |Date.now()| in JS to avoid those? We may use |performance.timing.navigationStart + performance.now()| https://developer.mozilla.org/en-US/docs/Web/API/Performance/now or something similar as an alternative:
unlike |Date.now()|, the values returned by |performance.now()| always increase at a constant rate, independent of the system clock (which might be adjusted manually or skewed by software like NTP)
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kripod/uuidv7/issues/2#issuecomment-928897286, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE4OHJYGLLCJCUUHO72UDTUEFOXXANCNFSM5E4S6NXQ.
v0.2.2 has just introduced a fix for system clock drifts: https://github.com/kripod/uuidv7/commit/2161e35a5dec7cc1a45e549126251291858ae383
Your custom clock use-case would be suited better by UUIDv8, which features highly customizable timestamps. I’m closing this for now, as this project aims to offer a lightweight implementation rather than providing low-level custom options. Thanks again for sharing your ideas 😊
@kripod thanks for that implementation, however I don't think that solution works when the process context can restart.
My situation involves process restart, and so I intend to persist the clock state on disk so I can ensure that my ids are always monotonic even after process restart.
I see, thanks for sharing that insight. I’m not sure why persisting clock state to disk would be necessary, as time passes in a monotonic manner. There is almost no chance that a process could restart within a single millisecond in the foreseeable future. Even if that happens, it’d take ~17 years in order to have a 1% probability of at least one collision when generating 1000 IDs per hour within the same millisecond.
I'm building a decentralized application that will run on user machines. Users who may reset their clock. I'd prefer to be foolproof and ensure that my uuid generation isn't broken inside the app even if the OS clocks have been reset. My application is persistent, so I can save the clock state or last generated ID and use that as a reference point.
I'm concerned that the usage of
Date
is not monotonic. I've tested this myself andDate
can give back the same datetime when done very closely.Furthermore if the OS clock drifts or is set backwards, I may want my application to be monotonic even then. So having the ability to provide a custom clock where I enforce monotonicity would be useful.
Can be helpful for testing and mocking if the clocksource can be dependency injected.