akkadotnet / akka.net

Canonical actor model implementation for .NET with local + distributed actors in C# and F#.
http://getakka.net
Other
4.71k stars 1.04k forks source link

Akka.Streams: `DivertTo` requires `NotUsed` materialization value instead of being generic #7091

Open Aaronontheweb opened 8 months ago

Aaronontheweb commented 8 months ago

Version Information Version of Akka.NET? v1.5.16 Which Akka.NET Modules? Akka.Streams

Describe the bug

I answered a question on Discord earlier today about "why does my Sink type not work with my Source type when I am using DivertTo" and I found the answer accordingly, while working on a proof of concept:

var actorSystem = ActorSystem.Create("Sys");

var source = Source.From(Enumerable.Range(0, 100));

var evenSink = Sink.ForEach<int>(i =>
{
    Console.WriteLine($"{i} is divisible by 2");
}).MapMaterializedValue(_ => NotUsed.Instance);

var threeSink = Sink.ForEach<int>(i =>
{
    Console.WriteLine($"{i} is divisible by 3");
}).MapMaterializedValue(_ => NotUsed.Instance);

var fiveSink = Sink.ForEach<int>(i =>
{
    Console.WriteLine($"{i} is divisible by 5");
}).MapMaterializedValue(_ => NotUsed.Instance);

var task = source.DivertTo(evenSink, i => i % 2 == 0)
.DivertTo(threeSink, i => i % 3 == 0)
.DivertTo(fiveSink, i => i % 5 == 0)
.RunWith(Sink.ForEach<int>(i => Console.WriteLine($"{i} is unhandled")), actorSystem);

await task;

The issue in this case is that DivertTo has a hard-coded NotUsed materialization value, so all of my other sinks I passed in had to use the MapMaterializationValue function to discard their Task materializations and convert it to NotUsed.

Expected behavior

I'd expect any Source<T, TMat> to work just fine inside a DivertTo without having to call MapMaterializedValue first - but there might be a very good reason from a graph construction standpoint why DivertTo is done this way - I just don't know what that might be off the top of my head.

Aaronontheweb commented 8 months ago

So to be clear: not sure if this is an actual bug or not

Aaronontheweb commented 8 months ago

I'm now wondering if this was a bone-headed mistake on my part and this is just the DivertTo taking on the materialization value of the Source<T>...