Class: PG::EM::Client::Helper::DeferrableGroup

Inherits:
Object
  • Object
show all
Includes:
EventMachine::Deferrable
Defined in:
lib/em-pg-client-helper/deferrable_group.rb

Overview

Fire a callback/errback when all of a group of deferrables is finished.

Essentially a "barrier" for deferrables; you define the set of deferrables you want to group together, and when they're all finished, only then does the callback(s) or errback(s) on this deferrable fire.

Defined Under Namespace

Classes: ClosedError

Instance Method Summary collapse

Constructor Details

#initialize {|_self| ... } ⇒ DeferrableGroup

Create a new deferrable group.

Yields:

  • (_self)

Yield Parameters:



19
20
21
22
23
24
25
# File 'lib/em-pg-client-helper/deferrable_group.rb', line 19

def initialize
	@closed      = false
	@failure     = nil
	@outstanding = []

	yield(self) if block_given?
end

Instance Method Details

#add(df) ⇒ EM::Deferrable

Add a new deferrable to this group.

Parameters:

  • df (EM::Deferrable)

    the deferrable to wait on.

Returns:

  • (EM::Deferrable)

    the same deferrable.

Raises:



38
39
40
41
42
43
44
45
46
# File 'lib/em-pg-client-helper/deferrable_group.rb', line 38

def add(df)
	if @closed
		raise ClosedError,
		      "This deferrable group is closed"
	end

	@outstanding << df
	df.callback { completed(df) }.errback { |ex| failed(df, ex) }
end

#closeObject

Tell the group that no further deferrables are to be added

If all the deferrables in a group are complete, the group can't be sure whether further deferrables may be added in the future. By requiring an explicit #close call before the group completes, this ambiguity is avoided. It does, however, mean that if you forget to close the deferrable group, your code is going to hang. Such is the risk of async programming.



57
58
59
60
# File 'lib/em-pg-client-helper/deferrable_group.rb', line 57

def close
	@closed = true
	maybe_done
end

#completed(df) ⇒ Object

Mark a deferrable as having been completed.

If this is the last deferrable in the group, then the callback/errback will be triggered.

Parameters:

  • df (EM::Deferrable)


69
70
71
72
# File 'lib/em-pg-client-helper/deferrable_group.rb', line 69

def completed(df)
	@outstanding.delete(df)
	maybe_done
end

#failed(df, ex) ⇒ Object

Register that a given deferrable completed, but has failed.

As soon as failed has been called, the deferrable group is guaranteed to fail, no matter how many of the deferrables in the group succeed. If this is the first deferrable in the group to have failed, then ex will be the exception passed to the errback, otherwise the exception will unfortunately be eaten by a grue.



82
83
84
85
# File 'lib/em-pg-client-helper/deferrable_group.rb', line 82

def failed(df, ex)
	@failure ||= ex
	completed(df)
end