Skip to content
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

Adding GUID v6 support when spec is complete #62090

Open
lucasfolino opened this issue Nov 26, 2021 · 9 comments
Open

Adding GUID v6 support when spec is complete #62090

lucasfolino opened this issue Nov 26, 2021 · 9 comments
Labels
area-System.Runtime needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration
Milestone

Comments

@lucasfolino
Copy link

lucasfolino commented Nov 26, 2021

I wanted to bring this to discussion to see what the thoughts where for supporting GUID v6 when it comes out. Currently there is no way to create a sequential GUID without use EF core. Since this Sequential guid seems to be SQL specific and there is no standard sequential GUID generator in dotnet core I want to discuss if the new versions of GUID will be supported. I suspect the base way to support the new GUID generation would require either a new factory which can generate v4 or v6 GUIDs or a new type of GUID. I understand we wouldn't want to break backwards comparability, but we will need a way to support both versions and I feel that this is am important piece of base functionality that should be included in dotnet core.

Adding IETF spec for reference:
https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Nov 26, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@ghost
Copy link

ghost commented Nov 26, 2021

Tagging subscribers to this area: @dotnet/area-system-runtime
See info in area-owners.md if you want to be subscribed.

Issue Details

I wanted to bring this to discussion to see what the thoughts where for supporting GUID v6 when it comes out. Currently there is no way to create a sequential GUID without use EF core. Since this Sequential guid seems to be SQL specific and there is no standard sequential GUID generator in dotnet core I want to discuss if the new versions of GUID will be supported. I suspect the base way to support the new GUID generation would require either a new factory which can generate v4 or v6 GUIDs or a new type of GUID. I understand we wouldn't want to break backwards comparability, but we will need a way to support both versions and I feel that this is am important piece of base functionality that should be included in dotnet core.

Author: lucasfolino
Assignees: -
Labels:

area-System.Runtime, untriaged

Milestone: -

@danmoseley
Copy link
Member

welcome @lucasfolino I see this is your first issue.

@ajcvickers thoughts? EF is mentioned here.

@GrabYourPitchforks
Copy link
Member

Non-v4 UUIDs were considered for the BCL previously and rejected (see #23868). I think much of that same reasoning would apply to this proposal. The draft spec mentions domain-specific concerns like unique machine identifiers to prevent collisions in clustered applications, etc.

Given that these concerns already dovetail with those of data access APIs, I would think that if there's the desire to do this work, any new APIs really belong in System.Data rather than on the base System.Guid type.

@lucasfolino
Copy link
Author

I disagree because before there was no RFC for anything beyond v5 which doesn't seem to be widely used. These would be based on an actual spec and therefore should be part of the base system and not part of SQL. The reason being that if other systems supply v6 GUID I may want to consume it and not have to talk to or should need to depend on a EF or a database for this support. Also there argument for rejecting was this functionality existed elsewhere. Also it seems the argument against was the older versions did not add anything and was going backwards. V1 and V5 don't seem to be as useful as V6 or later. I wouldn't be against if this implemented the entire RFC for V1 - V8, but it would make more sense to add v6 for Sequential GUIDs.

The original sequential GUID implementation was part of the BCL, but later moved out to EF since it was more in line with using on SQL server and not universal from DB to DB. If this follows the spec this would be universal and probably better to use once databases start supporting the new versions. I also feel in the future this should replace what is in SQL server since it will be a standard, but this is for dotnet and not SQL. I also think this should be revisited since it is a new spec. This should be treated no differently than HTTP 2/3 which is new specifications and not supporting something old or legacy. I don't know of any systems using GUID v1 or if they are it isn't apparent. New systems and other data sources will support this it would be best if dotnet did too. Ultimately it would be nice to support the whole spec, but I understand the SHA1 support was a no no, but this doesn't rely on that so the arguments made before are mute.

@GrabYourPitchforks
Copy link
Member

I understand the SHA1 support was a no no, but this doesn't rely on that so the arguments made before are mute.

The biggest arguments against v5 weren't SHA-1, but rather: (a) they're specialized use cases not suited to the generalized API already on System.Guid; and (b) successful community packages already existed to support them.

One of the examples I listed a few paragraphs above was that some of these have the concept of a machine id for deduplication purposes when two machines in a cluster attempt to generate a UUID at the same time. Do we add "machine id" as a first-class concept to the runtime and have Guid automatically pick it up somehow, do we say the app remains in charge of it and they need to pass a machineId parameter to the new Guid factory method, or something else? What about the clock sequence, which must be monotonically incrementing across all instances of the application for any given timestamp?

This is a very deep rabbit hole to start going down. Your example of HTTP2/3 is interesting, but it's something that can be done generally transparently. That didn't really require any thought on behalf of the caller. It's vastly different than an API where the very first thing we do is to ask the consumer, "Hey, it's time for a philosophical question! How do you define application?"

It's an interesting spec, but its usage is very specialized and it requires its callers to be acutely aware of usage nits. There's nothing wrong with any of that. We take such APIs all the time. But we generally try to keep them clustered to portions of code that are already dealing with these types of concerns. And the Guid primitive really doesn't seem like the right place.

@GrabYourPitchforks
Copy link
Member

Examples are always useful. Here's a strawman example of what an appropriate API might look like.

interface IUuidFactory
{
    Guid CreateNewUuid();
}

public class UuidFactorySingleAppInstance : IUuidFactory
{
    public UuidFactorySingleAppInstance(); // all state contained within this object, no caller params needed
}

public class UuidFactoryMultiAppInstance : IUuidFactory
{
    public UuidFactoryMultiAppInstance(int machineId);
}

public class UuidFactoryCustom : IUuidFactory
{
    public UuidFactoryCustom(IClockSequenceStore authority); // the authority (perhaps on a different machine?) for the monotonic counter associated with any given timestamp
}

static IUuidFactory factory = CreateFactoryPerYourAppsNeeds();
Guid newUuid = factory.CreateNewUuid();

No changes had to be made to Guid to support this scenario. All of the configuration & complexity sits in newly introduced higher-level factory types.

@lucasfolino
Copy link
Author

It doesn't need to be in the GUID primitive per se. The GUID primitive really doesn't need to change it can be used as the container of the data itself since it is just a bunch of bytes. I am not sure of the best place, but a GUID factory would be the best way to do this. I would say maybe the GUID primitive should change to just a data store, and have the factory that generates them. Then the GUID will call the static factory internally to when new GUID is called. This can default to v4, but also allow me to set the static generator which would be able to be changed. Or similar to how DateOnly and TimeOnly where added. Don't touch current GUID, but add a new GUID generator that returns the GUID struct. I am sure we can find a way, but I think it needs to be said that GUID needs a face lift and should be more explicit on what is being generated. In the future when there are multiple versions in use there is no easy way to know what version the GUID is. This isn't too important for now, but as a primitive it may be and should be treated as a fundamental piece of technology like JSON or datetime.

@Wraith2
Copy link
Contributor

Wraith2 commented Nov 27, 2021

but I think it needs to be said that GUID needs a face lift

Only if you can do that without breaking any consumers or regressing performance for them.

@tannergooding tannergooding added this to the Future milestone Jul 15, 2022
@tannergooding tannergooding added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed untriaged New issue has not been triaged by the area owner labels Jul 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Runtime needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration
Projects
None yet
Development

No branches or pull requests

5 participants