Skip to content

Fix some issues with Ignitor #15276

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

Merged
merged 1 commit into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 70 additions & 59 deletions src/Components/Ignitor/src/BlazorClient.cs

Large diffs are not rendered by default.

38 changes: 26 additions & 12 deletions src/Components/Ignitor/src/CancellableOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,50 @@
using System.Threading;
using System.Threading.Tasks;

#nullable enable
namespace Ignitor
{
internal class CancellableOperation<TResult>
{
public CancellableOperation(TimeSpan? timeout)
public CancellableOperation(TimeSpan? timeout, CancellationToken cancellationToken)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The bulk of the interesting changes are localized to this type. Here's what happens:

  1. We start a PrepareForNextBatch
  2. In the meanwhile, BlazorClient.Cancel is invoked (the server may or may not be dead at this point)
  3. CancellableOperation knows nothing about this and eventually times out.

This change associates the BlazorClient.Cancel with the operation and no-ops if the client has been cancelled

{
Timeout = timeout;

Completion = new TaskCompletionSource<TResult>(TaskContinuationOptions.RunContinuationsAsynchronously);
Completion.Task.ContinueWith(
(task, state) =>
{
var operation = (CancellableOperation<TResult>)state;
var operation = (CancellableOperation<TResult>)state!;
operation.Dispose();
},
this,
TaskContinuationOptions.ExecuteSynchronously); // We need to execute synchronously to clean-up before anything else continues


Cancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

if (Timeout != null && Timeout != System.Threading.Timeout.InfiniteTimeSpan && Timeout != TimeSpan.MaxValue)
{
Cancellation = new CancellationTokenSource(Timeout.Value);
CancellationRegistration = Cancellation.Token.Register(
(self) =>
{
var operation = (CancellableOperation<TResult>)self;
operation.Completion.TrySetCanceled(operation.Cancellation.Token);
operation.Cancellation.Dispose();
operation.CancellationRegistration.Dispose();
},
this);
Cancellation.CancelAfter(Timeout.Value);
}

CancellationRegistration = Cancellation.Token.Register(
(self) =>
{
var operation = (CancellableOperation<TResult>)self!;

if (cancellationToken.IsCancellationRequested)
{
// The operation was externally canceled before it timed out.
Dispose();
return;
}

operation.Completion.TrySetException(new TimeoutException($"The operation timed out after {Timeout}."));
operation.Cancellation?.Dispose();
operation.CancellationRegistration.Dispose();
},
this);
}

public TimeSpan? Timeout { get; }
Expand All @@ -62,3 +75,4 @@ private void Dispose()
}
}
}
#nullable restore
4 changes: 3 additions & 1 deletion src/Components/Ignitor/src/ComponentState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Ignitor
{
#nullable enable
public class ComponentState
{
public ComponentState(int componentId)
Expand All @@ -11,6 +12,7 @@ public ComponentState(int componentId)
}

public int ComponentId { get; }
public IComponent Component { get; }
public IComponent? Component { get; }
}
#nullable restore
}
2 changes: 2 additions & 0 deletions src/Components/Ignitor/src/ContainerNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;

#nullable enable
namespace Ignitor
{
public abstract class ContainerNode : Node
Expand Down Expand Up @@ -82,3 +83,4 @@ public void RemoveLogicalChild(int childIndex)
}
}
}
#nullable restore
10 changes: 7 additions & 3 deletions src/Components/Ignitor/src/ElementHive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

#nullable enable
namespace Ignitor
{
public class ElementHive
Expand Down Expand Up @@ -35,7 +37,7 @@ public void Update(RenderBatch batch)
}
}

public bool TryFindElementById(string id, out ElementNode element)
public bool TryFindElementById(string id, [NotNullWhen(true)] out ElementNode? element)
{
foreach (var kvp in Components)
{
Expand All @@ -49,7 +51,7 @@ public bool TryFindElementById(string id, out ElementNode element)
element = null;
return false;

bool TryGetElementFromChildren(Node node, out ElementNode foundNode)
bool TryGetElementFromChildren(Node node, out ElementNode? foundNode)
{
if (node is ElementNode elementNode &&
elementNode.Attributes.TryGetValue("id", out var elementId) &&
Expand Down Expand Up @@ -81,6 +83,7 @@ private void UpdateComponent(RenderBatch batch, int componentId, ArrayBuilderSeg
{
component = new ComponentNode(componentId);
Components.Add(componentId, component);

}

ApplyEdits(batch, component, 0, edits);
Expand Down Expand Up @@ -199,7 +202,7 @@ private void ApplyEdits(RenderBatch batch, ContainerNode parent, int childIndex,

case RenderTreeEditType.StepOut:
{
parent = parent.Parent;
parent = parent.Parent ?? throw new InvalidOperationException($"Cannot step out of {parent}");
currentDepth--;
childIndexAtCurrentDepth = currentDepth == 0 ? childIndex : 0; // The childIndex is only ever nonzero at zero depth
break;
Expand Down Expand Up @@ -469,3 +472,4 @@ public PermutationListEntry(int from, int to)
}
}
}
#nullable restore
4 changes: 3 additions & 1 deletion src/Components/Ignitor/src/ElementNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;

#nullable enable
namespace Ignitor
{
public class ElementNode : ContainerNode
Expand Down Expand Up @@ -87,7 +88,7 @@ internal Task SelectAsync(HubConnection connection, string value)
return DispatchEventCore(connection, Serialize(webEventDescriptor), Serialize(args));
}

public Task ClickAsync(HubConnection connection)
internal Task ClickAsync(HubConnection connection)
{
if (!Events.TryGetValue("click", out var clickEventDescriptor))
{
Expand Down Expand Up @@ -129,3 +130,4 @@ public ElementEventDescriptor(string eventName, ulong eventId)
}
}
}
#nullable restore
4 changes: 3 additions & 1 deletion src/Components/Ignitor/src/Error.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable
namespace Ignitor
{
public class Error
{
public string Stack { get; set; }
public string? Stack { get; set; }
}
}
#nullable restore
5 changes: 2 additions & 3 deletions src/Components/Ignitor/src/IComponent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

namespace Ignitor
{
Expand Down
6 changes: 5 additions & 1 deletion src/Components/Ignitor/src/Node.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

#nullable enable

namespace Ignitor
{
public abstract class Node
{
public virtual ContainerNode Parent { get; set; }
public virtual ContainerNode? Parent { get; set; }
}
}

#nullable restore
7 changes: 5 additions & 2 deletions src/Components/Ignitor/src/NodeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System;
using System.IO;

#nullable enable

namespace Ignitor
{
internal static class NodeSerializer
Expand Down Expand Up @@ -96,7 +98,7 @@ private void SerializeElement(ElementNode elementNode)
if (attribute.Value != null)
{
Write("=\"");
Write(attribute.Value.ToString());
Write(attribute.Value.ToString()!);
Write("\"");
}
}
Expand All @@ -113,7 +115,7 @@ private void SerializeElement(ElementNode elementNode)
if (properties.Value != null)
{
Write("=\"");
Write(properties.Value.ToString());
Write(properties.Value.ToString()!);
Write("\"");
}
}
Expand Down Expand Up @@ -194,3 +196,4 @@ private void WriteIndent()
}
}
}
#nullable restore
2 changes: 2 additions & 0 deletions src/Components/Ignitor/src/Operations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Concurrent;

#nullable enable
namespace Ignitor
{
public sealed class Operations
Expand All @@ -18,3 +19,4 @@ public sealed class Operations
public ConcurrentQueue<CapturedJSInteropCall> JSInteropCalls { get; } = new ConcurrentQueue<CapturedJSInteropCall>();
}
}
#nullable restore
5 changes: 4 additions & 1 deletion src/Components/Ignitor/src/RenderBatchReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using System;
using System.Text;

#nullable enable

namespace Ignitor
{
public static class RenderBatchReader
Expand Down Expand Up @@ -206,7 +208,7 @@ private static ArrayRange<ulong> ReadDisposedEventHandlerIds(ReadOnlySpan<byte>
return new ArrayRange<ulong>(Array.Empty<ulong>(), 0);
}

private static string ReadString(ReadOnlySpan<byte> data, string[] strings)
private static string? ReadString(ReadOnlySpan<byte> data, string[] strings)
{
var index = BitConverter.ToInt32(data.Slice(0, 4));
return index >= 0 ? strings[index] : null;
Expand Down Expand Up @@ -279,3 +281,4 @@ public ReadOnlySpan<byte> GetStringTableIndexes(ReadOnlySpan<byte> data)
}
}
}
#nullable restore