Skip to content

Gracefully stopping fibers #3561

@Papierkorb

Description

@Papierkorb

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:

  1. Have a sorted list of requests to be made
  2. Spawn a fixed amount of fibers
  3. Each fiber takes out a request from the list. If the list is empty, stop the fiber. If all are stopped, break.
  4. Do the requests. Each response may yield either new requests (Which are then added to the list), OR the result.
  5. If a result was found, stop all fibers and return it. Else, each fiber goes 3.
  6. 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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions