.NET: fix: FanIn Edge does not work (#541)

* fix: FanIn Edge does not work

We were not creating the state for FanIn edge in EdgeMap correctly, leading to crashes. After fixing that, it turns out the logic in FanInEdgeRunner was only forwarding the last message, not all of them.

* fix: Remove duplicate code and fix typo
This commit is contained in:
Jacob Alber
2025-08-28 18:25:57 -04:00
committed by GitHub
Unverified
parent 0c28935382
commit e1147273da
8 changed files with 392 additions and 10 deletions
@@ -32,6 +32,11 @@ internal class EdgeMap
_ => throw new NotSupportedException($"Unsupported edge type: {edge.EdgeType}")
};
if (edgeRunner is FanInEdgeRunner fanInRunner)
{
this._fanInState[edge.Data.Connection] = fanInRunner.CreateState();
}
this._edgeRunners[edge.Data.Connection] = edgeRunner;
}
@@ -12,12 +12,12 @@ internal class FanInEdgeRunner(IRunnerContext runContext, FanInEdgeData edgeData
public FanInEdgeState CreateState() => new(this.EdgeData);
public async ValueTask<object?> ChaseAsync(string sourceId, MessageEnvelope envelope, FanInEdgeState state, IStepTracer? tracer)
public async ValueTask<IEnumerable<object?>> ChaseAsync(string sourceId, MessageEnvelope envelope, FanInEdgeState state, IStepTracer? tracer)
{
if (envelope.TargetId != null && this.EdgeData.SinkId != envelope.TargetId)
{
// This message is not for us.
return null;
return [];
}
object message = envelope.Message;
@@ -25,18 +25,23 @@ internal class FanInEdgeRunner(IRunnerContext runContext, FanInEdgeData edgeData
if (releasedMessages is null)
{
// Not ready to process yet.
return null;
return [];
}
Executor target = await this.RunContext.EnsureExecutorAsync(this.EdgeData.SinkId, tracer)
.ConfigureAwait(false);
.ConfigureAwait(false);
if (target.CanHandle(message.GetType()))
List<Task<object?>> messageTasks = [];
foreach (var messageTask in releasedMessages)
{
tracer?.TraceActivated(target.Id);
return await target.ExecuteAsync(message, envelope.MessageType, this.BoundContext)
.ConfigureAwait(false);
if (target.CanHandle(messageTask.GetType()))
{
tracer?.TraceActivated(target.Id);
messageTasks.Add(target.ExecuteAsync(messageTask, envelope.MessageType, this.BoundContext).AsTask());
}
}
return null;
return await Task.WhenAll(messageTasks.ToArray()).ConfigureAwait(false);
}
}