Skip to content

Error swallowed inside second task if the first task runs a loop #378

@kwboyd-shopify

Description

@kwboyd-shopify

Hi! I'm running into an issue when using Async::Barrier with two infinitely running loops. When I raise a StandardError inside the second task, that task stops, but the barrier continues running the first task, despite me running barrier.wait and ensuring barrier.stop. When I raise a StandardError inside the first task, that ensure block does get hit and the barrier does stop both tasks.

Here's a short reproduction of the issue:

require "async"
require "async/barrier"
class Runner
  def run
    barrier = Async::Barrier.new

    Async do
      barrier.async(annotation: "Loop 1") do
        loop do
          puts "Running loop 1"
          sleep(1)
                    
          # This error will bring us to the `ensure` block and stops the barrier
          # raise "Error 1"
          sleep(1)
        end
      end

      barrier.async(annotation: "Loop 2") do
        loop do
          puts "Running loop 2"
          sleep(1)

          # This error will bring NOT us to the `ensure` block and does not stop the barrier
          raise "Error 2"
          sleep(1)
        end
      end

      begin
        barrier.wait
      ensure
        puts "Stopping barrier"
        barrier.stop
      end
    end
  rescue StandardError, Exception => e
    raise e
  end
end

Runner.new().run

This only seems to occur if the first task runs an infinite loop. The second task running in a loop or not doesn't affect the outcome.

I found a few workarounds:

  1. Having the second task raise an Exception instead
  2. Adding barrier.stop if barrier.tasks.to_a.any? { |node| !node.task.alive? } inside the loop of the first task

Thanks in advance for any insight!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions