Skip to content

Commit f03cca4

Browse files
committed
Release cleanup state machine as soon as possible
1 parent 690d9d2 commit f03cca4

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

src/cluster/DotNext.Net.Cluster/Net/Cluster/Consensus/Raft/StateMachine/WriteAheadLog.Flusher.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ partial class WriteAheadLog
2828
[AsyncMethodBuilder(typeof(SpawningAsyncTaskMethodBuilder))]
2929
private async Task FlushAsync(long previousIndex, TimeSpan timeout, CancellationToken token)
3030
{
31-
var cleanupTask = Task.CompletedTask;
31+
// Weak ref tracks the task, but allows GC to collect associated state machine
32+
// as soon as possible. While the task is running, it cannot be collected, because it's referenced
33+
// by the async state machine.
34+
var cleanupTask = GCHandle.Alloc(Task.CompletedTask, GCHandleType.Weak);
3235
try
3336
{
3437
for (long newIndex, oldSnapshot = SnapshotIndex, newSnapshot;
@@ -59,17 +62,21 @@ private async Task FlushAsync(long previousIndex, TimeSpan timeout, Cancellation
5962
lockManager.ReleaseReadLock();
6063
}
6164
}
62-
63-
if (cleanupTask.IsCompleted && oldSnapshot < newSnapshot)
64-
cleanupTask = CleanUpAsync(newSnapshot, token);
65+
66+
if (cleanupTask.Target is null or Task { IsCompletedSuccessfully: true } && oldSnapshot < newSnapshot)
67+
cleanupTask.Target = CleanUpAsync(newSnapshot, token);
6568

6669
manualFlushQueue.Drain();
6770
await flushTrigger.WaitAsync(timeout, token).ConfigureAwait(false);
6871
}
6972
}
70-
catch (OperationCanceledException e) when (e.CancellationToken == token)
73+
catch (OperationCanceledException e) when (e.CancellationToken == token && cleanupTask.Target is Task target)
74+
{
75+
await target.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
76+
}
77+
finally
7178
{
72-
await cleanupTask.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
79+
cleanupTask.Free();
7380
}
7481
}
7582

0 commit comments

Comments
 (0)