deferrable_gratification icon indicating copy to clipboard operation
deferrable_gratification copied to clipboard

Join that does not swallow failures

Open ept opened this issue 13 years ago • 0 comments

I spent a while trying to track down a bug that was masked by DG::join_successes. What happened was something like this:

def operation(param)
  something_async(param).transform do |value|
    call_some_method_that_does_not_exist! # raises NameError
  end
end

def one_two_three
  DG::join_successes operation('one'), operation('two'), operation('three')
end

That NameError caused each operation to fail, but because join_successes discarded the failures, one_two_three succeeded. I had error logging on an errback, but it never got logged, which left me scratching my head for a while.

In a context where the constituent deferrables are expected to succeed, it would be nicer for the join combinator to immediately escalate any failure. Something like this:

# If any of the joined deferrables fails, fails immediately with that failure's error.
# Otherwise waits for all deferrables to succeed, and succeeds with an array of success results.
class JoinCarefully < DeferrableGratification::Combinators::Join
  private
  def done?
    failures.length > 0 || all_completed?
  end

  def finish
    if failures.empty?
      succeed(successes)
    else
      fail(failures.first)
    end
  end
end

ept avatar Feb 06 '12 04:02 ept