diff --git a/lib/async/container/controller.rb b/lib/async/container/controller.rb index 97e4394..294450b 100644 --- a/lib/async/container/controller.rb +++ b/lib/async/container/controller.rb @@ -11,17 +11,9 @@ module Async module Container - module Atomic - def atomic(&block) - ::Thread.handle_interrupt(Exception => :never, &block) - end - end - # Manages the life-cycle of one or more containers in order to support a persistent system. # e.g. a web server, job server or some other long running system. class Controller - include Atomic - SIGHUP = Signal.list["HUP"] SIGINT = Signal.list["INT"] SIGTERM = Signal.list["TERM"] @@ -194,14 +186,17 @@ def run # I thought this was the default... but it doesn't always raise an exception unless you do this explicitly. # We use `Thread.current.raise(...)` so that exceptions are filtered through `Thread.handle_interrupt` correctly. interrupt_action = Signal.trap(:INT) do + # $stderr.puts "Received INT signal, terminating...", caller ::Thread.current.raise(Interrupt) end terminate_action = Signal.trap(:TERM) do + # $stderr.puts "Received TERM signal, terminating...", caller ::Thread.current.raise(Terminate) end hangup_action = Signal.trap(:HUP) do + # $stderr.puts "Received HUP signal, restarting...", caller ::Thread.current.raise(Hangup) end diff --git a/lib/async/container/group.rb b/lib/async/container/group.rb index 52e2e08..f3a0989 100644 --- a/lib/async/container/group.rb +++ b/lib/async/container/group.rb @@ -20,6 +20,10 @@ def initialize @queue = nil end + def inspect + "#<#{self.class} running=#{@running.size}>" + end + # @attribute [Hash(IO, Fiber)] the running tasks, indexed by IO. attr :running diff --git a/lib/async/container/notify/console.rb b/lib/async/container/notify/console.rb index ea94f98..0c8b0ef 100644 --- a/lib/async/container/notify/console.rb +++ b/lib/async/container/notify/console.rb @@ -13,7 +13,7 @@ module Notify # Implements a general process readiness protocol with output to the local console. class Console < Client # Open a notification client attached to the current console. - def self.open!(logger = ::Console.logger) + def self.open!(logger = ::Console) self.new(logger) end diff --git a/test/async/container/.bad.rb b/test/async/container/.bad.rb index 8c3b4c2..d655b16 100755 --- a/test/async/container/.bad.rb +++ b/test/async/container/.bad.rb @@ -6,6 +6,8 @@ require_relative '../../../lib/async/container/controller' +$stdout.sync = true + class Bad < Async::Container::Controller def setup(container) container.run(name: "bad", count: 1, restart: true) do |instance| @@ -13,12 +15,10 @@ def setup(container) # instance.ready! $stdout.puts "Ready..." - $stdout.flush sleep ensure $stdout.puts "Exiting..." - $stdout.flush end end end diff --git a/test/async/container/.dots.rb b/test/async/container/.dots.rb index e38381c..8050b0f 100755 --- a/test/async/container/.dots.rb +++ b/test/async/container/.dots.rb @@ -13,6 +13,9 @@ def setup(container) container.run(name: "dots", count: 1, restart: true) do |instance| instance.ready! + # This is to avoid race conditions in the controller in test conditions. + sleep 0.1 + $stdout.write "." sleep diff --git a/test/async/container/.graceful.rb b/test/async/container/.graceful.rb index 51d63b0..f5f1e9d 100755 --- a/test/async/container/.graceful.rb +++ b/test/async/container/.graceful.rb @@ -12,6 +12,10 @@ class Graceful < Async::Container::Controller def setup(container) container.run(name: "graceful", count: 1, restart: true) do |instance| instance.ready! + + # This is to avoid race conditions in the controller in test conditions. + sleep 0.1 + clock = Async::Clock.start original_action = Signal.trap(:INT) do