-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Hi,
While working on the torrent
shard, I came across the need to tell fibers to stop running forever regularly. Often fixed through other means, like a running
bool, I came across the following use-case where this is not easily doable:
- Have a sorted list of requests to be made
- Spawn a fixed amount of fibers
- Each fiber takes out a request from the list. If the list is empty, stop the fiber. If all are stopped, break.
- Do the requests. Each response may yield either new requests (Which are then added to the list), OR the result.
- If a result was found, stop all fibers and return it. Else, each fiber goes 3.
- After each fiber ran a request, another "control" fiber gets sent (through a Channel) the most promising request from each fiber. Now it checks if the most promising request from these requests is better than the previously known best. If it is not, break with no result.
The control fiber is basically doing: fiber_count.times{ candidates.receive }
The issue is, if the result is found, or the list is empty, the control fiber will now wait in the loop above forever, which would basically leak it. Another approach would be having yet another Channel which is monitored by the control fiber (Through select
), and if received, halts the control fiber.
However, I'd love to have a primitive which lets me send some kind of message to a Fiber, any Fiber, to please stop itself.
A solution employed by languages like Java is to inject an exception (java.lang.Thread.interrupt()
). This is quite nice, as properly implemented Fibers would then release resources through ensure
/rescue
. It would also kick a sleeping/waiting fiber out of a blocking call like Channel#receive
or IO::FileDescriptor#read
.
A second solution could be a Fiber#close
method, which sets a flag which is checked in Fiber#resume
, and then runs all ensure
blocks.
Ideas?