Channel monitoring/statistics

Before I reinvent the wheel, is there any conventional solution to track statistics on the state of channels during execution? E.g what’s the distribution of channel length over time (not size but items in channel) or distribution of wall time for a take!(channel)?

My simple use case: I have several pairs of consumers/producers that are chained (i.e task 1 writes to channel A, task 2 reads from channel A and writes to channel B). Being able to easily peek at channel dynamics might provide nice hints for debugging.

I skimmed over BenchmarkTools.jl, which deals with distributions of performance metrics (time), but I don’t think it’s quite it? Apologies if I just need to RTFM a bit more.

Thanks!

There is no mechanism for this that I know of, which is reasonable to expect since it would add unnecessary overhead for the majority of use cases. I would say you should probably roll your own type that does this bookkeeping automatically; although do beware that if you do any multithreading, you’ll want to make sure that you use locking/atomics to update any global structures that you maintain.

1 Like

Thanks Julian. I think the overhead can be managed (e.g. for take! you can record a time with a certain probability, or for channel length you could add channels to a list and have a separate task poll and record channel length and sleep). But indeed if there’s nothing that already exists I’ll roll my own stuff. I’m also aware that adding this extra tracking might even affect timing and as such the thread dynamics that happens without tracking.

I’m curious to hear whether this idea sounds like a generally sane thing, or completely misguided and there are better ways to debug asynchronous/threaded code. Any thoughts?

I too would like a simple function that provided the number of items currently in a channel. Did you manage to solve your problem? I don’t want to take! them all one by one, checking all the time if the channel isready(), count them until it’s empty, and then put them all back. That seems like a waste of time but it’s the only thing I can think of. :flushed: Alternatively I could use a circular buffer from DataStructures.jl but that means I can’t so easily reference them across tasks. Any help would be appreciated.