socketry / async

An awesome asynchronous event-driven reactor for Ruby.
MIT License
2.04k stars 85 forks source link

[Question] How to stop a fiber? #263

Open jsaak opened 11 months ago

jsaak commented 11 months ago

I have still no idea how to stop a Fiber from running (unschedule). I was told that i can raise an exception, but it is not working as i hoped. Can you help me how to do that?

In this code i was expecting @fib1 to exit, but it does not exit ever.

Do I have any alternative options?

require 'async'

Fiber.set_scheduler(Async::Scheduler.new)

@fib1 = Fiber.schedule do
  puts 'entering fiber 1'
  sleep 1
  @fib2.raise
  puts 'exiting fiber 1'
end

@fib2 = Fiber.schedule do
  puts 'entering fiber 2'
  begin
    sleep 4
  rescue
    puts 'got exception'
  end
  puts 'exiting fiber 2'
end
jsaak commented 11 months ago

reading the source of Task, i found this:

Fiber.scheduler.raise(@fib2, "Stop")

And it seems to be working fine. Any reason Fiber.raise works different?

ioquatix commented 11 months ago

The problem with Fiber.raise is that it doesn't know how to schedule the original fiber that called it and it does an implicit transfer.

We should probably fix this in Ruby itself, so that it just works as expected.

Let me look into this issue in more detail this week.

jsaak commented 11 months ago

Thanks! I am happy that you think it is a bug too. In the meantime i will use Fiber.scheduler.raise() .

(My program is a bit more complicated than the one i posted, i lost some hair figuring this out :)

ioquatix commented 11 months ago

If you check Fiber.scheduler.raise you will see it handles the scheduling correctly.