-
Notifications
You must be signed in to change notification settings - Fork 473
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
Feature/recover whole path #8120
base: master
Are you sure you want to change the base?
Changes from 15 commits
5a6d98d
41067ed
7ad5fa4
3e64e9f
819b3d2
c2e15f3
a963b3f
4e238a9
30dbd68
aa543c2
5c5471c
ba014ff
fbe9db0
b1d0505
3aac29d
1767de1
fbea83a
e8a53e5
c14ccbc
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 |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System.Threading; | ||
using FluentAssertions; | ||
using Nethermind.Core.Extensions; | ||
using Nethermind.Core.Utils; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Core.Test; | ||
|
||
public class AutoCancelTokenSourceTests | ||
{ | ||
[Test] | ||
public void AutoCancelOnExitClosure() | ||
{ | ||
CancellationToken TaskWithInnerCancellation(CancellationToken token) | ||
{ | ||
using AutoCancelTokenSource cts = token.CreateChildTokenSource(); | ||
return cts.Token; | ||
} | ||
|
||
TaskWithInnerCancellation(default).IsCancellationRequested.Should().BeTrue(); | ||
} | ||
|
||
[Test] | ||
public void AutoCancelPropagateParentCancellation() | ||
{ | ||
using CancellationTokenSource cts = new CancellationTokenSource(); | ||
|
||
using AutoCancelTokenSource acts = cts.Token.CreateChildTokenSource(); | ||
|
||
acts.Token.IsCancellationRequested.Should().BeFalse(); | ||
|
||
cts.Cancel(); | ||
|
||
acts.Token.IsCancellationRequested.Should().BeTrue(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace Nethermind.Core.Tasks; | ||
|
||
public static class Wait | ||
{ | ||
/// <summary> | ||
/// Wait for any of the task that passed the predicate and forward the result, or all of the task to complete. | ||
/// </summary> | ||
/// <param name="cond"></param> | ||
/// <param name="tasks"></param> | ||
/// <typeparam name="T"></typeparam> | ||
/// <returns></returns> | ||
public static async Task<T> ForPassingTask<T>(Func<T, bool> cond, params IEnumerable<Task<T>> tasks) | ||
{ | ||
HashSet<Task<T>> taskSet = new HashSet<Task<T>>(tasks); | ||
while (taskSet.Any()) | ||
{ | ||
Task<T> resolved = await Task.WhenAny<T>(taskSet); | ||
taskSet.Remove(resolved); | ||
|
||
T result = await resolved; | ||
|
||
if (cond(result)) | ||
{ | ||
// Its ok, then immediately return. | ||
return result; | ||
} | ||
|
||
if (!taskSet.Any()) | ||
{ | ||
// No more tasks, just return the last one. | ||
return result; | ||
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. shouldn't we return null or just TaskCompleated with default value? 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. Hmmm... don't know. 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. Well, it does make nullability simple. |
||
} | ||
|
||
// Otherwise, we try WhenAny again. | ||
} | ||
|
||
throw new UnreachableException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using System.Threading; | ||
|
||
namespace Nethermind.Core.Utils; | ||
|
||
/// <summary> | ||
/// Automatically cancel and dispose underlying cancellation token source. | ||
/// Make it easy to have golang style defer cancel pattern. | ||
/// </summary> | ||
public readonly struct AutoCancelTokenSource(CancellationTokenSource cancellationTokenSource) : IDisposable | ||
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. why not derive from CancellationTokenSource? 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 prefer not to use inheritance. 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 somewhat agree, but it IS a CancellationTokenSource, so it makes some sense |
||
{ | ||
public CancellationToken Token => cancellationTokenSource.Token; | ||
|
||
public static AutoCancelTokenSource ThatCancelAfter(TimeSpan delay) | ||
{ | ||
CancellationTokenSource cancellationTokenSource = new(); | ||
cancellationTokenSource.CancelAfter(delay); | ||
return new AutoCancelTokenSource(cancellationTokenSource); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
cancellationTokenSource.Cancel(); | ||
cancellationTokenSource.Dispose(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,7 +204,7 @@ private void UpdateValue(ref decimal? currentValue, decimal newValue) | |
{ | ||
return (long?)(transferSpeedType switch | ||
{ | ||
TransferSpeedType.Latency => _averageLatency, | ||
TransferSpeedType.Latency => _averageLatency ?? 10000, | ||
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. const from some timeout? int.MaxValue? |
||
TransferSpeedType.NodeData => _averageNodesTransferSpeed, | ||
TransferSpeedType.Headers => _averageHeadersTransferSpeed, | ||
TransferSpeedType.Bodies => _averageBodiesTransferSpeed, | ||
|
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.
Can we make it span?
LINQ style naming?
AnyWhere
or justAny
- in LINQ it has optional parameter:https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=net-8.0#system-linq-enumerable-any-1(system-collections-generic-ienumerable((-0))-system-func((-0-system-boolean)))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.
Because its an async code.
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.
Ok the naming comment still stands