Closed oeoeaio closed 1 year ago
The ideal solution for this is to use a linked list. Short of a native implementation, we could fall back to using a native Ruby mutex/queue. It might even be faster, but the semantics aren’t quite the same. A Ruby mutex uses a linked list internally and my goal was to preserve FIFO order. I like your PR but I think we might need to be a little more sensitive to order and I’m not sure about performance either.
Do you mind opening another PR using Thread::Queue as the queue? Let’s see if it works. In Ruby 3+ Thread::Queue supports non-blocking fibers.
Related to #176
We found that calling
dequeue
on instances ofQueue
(andLimitedQueue
) inside aTask.with_timeout
block inside a loop will result in fibers accumulating in the@waiting
list for the Queue in the absence of any other fiber signalling theQueue
, leading to a memory leak.Our short term fix for this was just to manually
signal
theQueue
whenever the timeout was reached, but this only works where a single fibre is waiting on the queue with a timeout in a loop.Switching to using a
Set
instead of anArray
to hold the list of waiting fibres resolves the core issue. I don't think this will break anything as I can't really see a use case for having the same fibre in the@waiting
list multiple times.Keen for input on what tests might be appropriate for this, if any. Is suppose the main thing is that this change does not break the existing test suite.
Types of Changes
Contribution
Profiling code
Profiling before this change
retained memory by location
retained memory by class
Profiling after this change
retained memory by location
retained memory by class