socketry / async

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

Graceful shutdown #336

Closed ioquatix closed 3 months ago

ioquatix commented 3 months ago

In general, users should expect ensure blocks to work normally (sequentially).

Transient tasks do not keep the reactor alive. e.g.

Async do
  Async(transient: true) do
    sleep
  ensure
    sleep 1; $stderr.write "."
  end
end

Before this PR, the above program will not print any dot. After this PR, the program will print a dot. This allows transient tasks to clean up more robustly. The downside is, a badly behaving transient task may stall the event loop from exiting. However, Ctrl-C will interrupt the event loop again and cause it to exit.

Types of Changes

Contribution

ioquatix commented 3 months ago
require_relative 'lib/async'

reactor = nil

begin
    Async do |task|
        reactor = task.reactor

        Async(transient: true) do
            $stderr.puts "Hello, World!"
            sleep
        ensure
            $stderr.puts "Goodbye, World!"
            sleep
        end
    end
ensure
    binding.irb
end

Running this program and pressing Ctrl-C confirms the behaviour too.