-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
Store event handler IDs as longs. Fixes #12058 #12305
Changes from all commits
86b5aeb
d5ecb78
c901793
2ccf583
709761d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Components.RenderTree | |
/// <summary> | ||
/// Represents an entry in a tree of user interface (UI) items. | ||
/// </summary> | ||
[StructLayout(LayoutKind.Explicit)] | ||
[StructLayout(LayoutKind.Explicit, Pack = 4)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The existing TS-side code already expects 36. We could change it to 40 but with this line, there's no need. |
||
public readonly struct RenderTreeFrame | ||
{ | ||
// Note that the struct layout has to be valid in both 32-bit and 64-bit runtime platforms, | ||
|
@@ -90,7 +90,7 @@ public readonly struct RenderTreeFrame | |
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Attribute"/> | ||
/// gets the ID of the corresponding event handler, if any. | ||
/// </summary> | ||
[FieldOffset(8)] public readonly int AttributeEventHandlerId; | ||
[FieldOffset(8)] public readonly ulong AttributeEventHandlerId; | ||
|
||
/// <summary> | ||
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Attribute"/>, | ||
|
@@ -267,7 +267,7 @@ private RenderTreeFrame(int sequence, bool isMarkup, string textOrMarkup) | |
} | ||
|
||
// Attribute constructor | ||
private RenderTreeFrame(int sequence, string attributeName, object attributeValue, int attributeEventHandlerId, string attributeEventUpdatesAttributeName) | ||
private RenderTreeFrame(int sequence, string attributeName, object attributeValue, ulong attributeEventHandlerId, string attributeEventUpdatesAttributeName) | ||
: this() | ||
{ | ||
FrameType = RenderTreeFrameType.Attribute; | ||
|
@@ -337,7 +337,7 @@ internal RenderTreeFrame WithAttributeSequence(int sequence) | |
internal RenderTreeFrame WithComponent(ComponentState componentState) | ||
=> new RenderTreeFrame(Sequence, componentSubtreeLength: ComponentSubtreeLength, ComponentType, componentState, ComponentKey); | ||
|
||
internal RenderTreeFrame WithAttributeEventHandlerId(int eventHandlerId) | ||
internal RenderTreeFrame WithAttributeEventHandlerId(ulong eventHandlerId) | ||
=> new RenderTreeFrame(Sequence, attributeName: AttributeName, AttributeValue, eventHandlerId, AttributeEventUpdatesAttributeName); | ||
|
||
internal RenderTreeFrame WithAttributeValue(object attributeValue) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ internal class RenderBatchBuilder : IDisposable | |
// Primary result data | ||
public ArrayBuilder<RenderTreeDiff> UpdatedComponentDiffs { get; } = new ArrayBuilder<RenderTreeDiff>(); | ||
public ArrayBuilder<int> DisposedComponentIds { get; } = new ArrayBuilder<int>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should component ids be on the same boat? I can imagine that if we don't want to ever wrap around an event, it might be even more important for components, as it might be the case that 1 event triggers multiple component instantiations. Thoughts? I know the struct layout might get more complicated if we add 4 more bytes. But I think its a matter of being better safe than sorry. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’m open to it, but it will be quite a lot more disruptive than the event handler ID change, as component IDs are used in so many more places. To run out of IDs, you’d need to do something like instantiate 1000 components per second continuously for 25 days (in one circuit). I think we could say that is impractical for lots of reasons. One cheaper option would just be to change any public API for component IDs to be ulong, which leaves us the option of changing the underlying storage in the future if we want. |
||
public ArrayBuilder<int> DisposedEventHandlerIds { get; } = new ArrayBuilder<int>(); | ||
public ArrayBuilder<ulong> DisposedEventHandlerIds { get; } = new ArrayBuilder<ulong>(); | ||
|
||
// Buffers referenced by UpdatedComponentDiffs | ||
public ArrayBuilder<RenderTreeEdit> EditsBuffer { get; } = new ArrayBuilder<RenderTreeEdit>(64); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know our events are always positive and that we are never going to wrap around an ulong, but I'm worried about using unsigned types in here just because we pretty much don't ever use them and because I'm not confident on all the integration issues this might bring, from serialization, to method invocation, etc. Id rather if possible we simply use a long value as it achieves our goal and is less likely to cause issues in the future.
That said, It might be a case of me being paranoid about this for no reason. I'm just scared of the unknowns using this brings, as I don't think there's an API (or very few APIs) in ASP.NET or .NET that specifically use them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I picked ulong because it was easier to make robust:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't share your concerns 😆 I've used ulong before.