Cysharp / MessagePipe

High performance in-memory/distributed messaging pipeline for .NET and Unity.
MIT License
1.46k stars 105 forks source link

Subscription is called multiple times if you resubscribe at the same frame in async task #134

Open nicloay opened 1 month ago

nicloay commented 1 month ago

Message brocker use the following Publish method and here is how it take subscriber list handlers.GetValues() What happens is that I trigger the publisher (in my case from input) and then subscribe to the same event again

private ISubscriber<ButtonClickMsg> _testSubscriber; 
private async UniTask RunLoop()
{
    while (true)
    {
        await _testSubscriber.FirstAsync(default);
        Debug.Log(">> called 4 times instead of 1 <<");
    }
}

And never the less _testPublisher will be called once, you will see debug.log 4 times,

For the temporary solution I copy the subscriber array to another array, so new value will not be considered, but there are probably better ways of handling this

So in MessageBrocker.cs line 48 I have this

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public void Publish(TMessage message)
        {
            var array =  handlers.GetValues().ToArray(); // copy array here

            for (int i = 0; i < array.Length; i++)
            {
                array[i]?.Handle(message);
            }
        }
huylqnothing commented 1 month ago

same issue here, they did not fix it. I guess would have to delay a frame until they handle this.