rebus-org / Rebus

:bus: Simple and lean service bus implementation for .NET
https://mookid.dk/category/rebus
Other
2.26k stars 355 forks source link

How-to know if Rebus is processing #846

Closed AndreaCuneo closed 4 years ago

AndreaCuneo commented 4 years ago

Hi,

while using Rebus under test, not the FakeBus but the full Rebus just with in memory transport, I need a way to check if "there is still work ongoing". That means messages in queue or messaging in execution that may trigger new messages.

I've checked the InMemNetwork from which I can know the Count() but I've no way to know if one message is in processing.

I was thinking to something like IBus.Idle that would be flagged if all Workers are Idle defined as "last time I tried to Receive, I got no messages and I'm not processing any".

Do you have a way I can add this feature from the outside, as an hack, for example using a static global interlocked exchange integer to test it out? I'd like not to have use local Rebus build instead of Nuget packages while trying this out.

mookid8000 commented 4 years ago

Rebus' backoff strategy might have what you're after... the default implementation counts time elapsed running idle, to be able to look up a time to delay polling for the next message.... so if you insert your own backoff strategy (possibly as a decorator), then it should be possible to snatch that information somehow.

You can read about the backoff strategy here on the wiki: https://github.com/rebus-org/Rebus/wiki/Back-off-strategy

The default implementation is here: https://github.com/rebus-org/Rebus/blob/master/Rebus/Workers/ThreadPoolBased/DefaultBackoffStrategy.cs

AndreaCuneo commented 4 years ago

Thanks for the pointer and checking me out. I looked at it and unless I looked at it with the wrong angle, I do not understand how to correctly use it.

Looking at https://github.com/rebus-org/Rebus/blob/master/Rebus/Workers/ThreadPoolBased/ThreadPoolWorker.cs it uses WaitNoMessageAsync() if no messages has been fetched. This can be used to check if the worker is Idle but I don't find a way using BackoffStrategy to check if another one is processing a message.

It's unclear to me if the number of WaitNoMessageAsync() currently "waiting" is linked to the number of workers or the max parallelism or a combination of both. Any pointer?

mookid8000 commented 4 years ago

In DefaultBackoffStrategy in this methods you can see how it detects for how long it has been running idle.

My though was that you could maybe use the same way of detecting idle time, and then trigger a ManualResetEvent or a CancellationToken or something like that after e.g. 1 s of running idle....