module Delayer::Deferred::Deferredable::Chainable

Attributes

child[R]

Public Instance Methods

add_awaited(awaitable) click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 80
def add_awaited(awaitable)
  @awaited = [*awaited, awaitable].freeze
  self
end
add_child(chainable) click to toggle source

子を追加する。 Delayer::Deferred::Chainable を直接指定できる。通常外部から呼ぶときは nexttrap メソッドを使うこと。 このメソッドはスレッドセーフです。

Args

chainable

子となるDeferred

Return

必ず chainable を返す

Raise

Delayer::Deferred::SequenceError

既に子が存在している場合

# File lib/delayer/deferred/deferredable/chainable.rb, line 51
def add_child(chainable)
  change_sequence(:get_child) do
    chainable.parent = self
    @child = chainable
  end
end
add_child_observer(observer) click to toggle source

子が追加された時に一度だけコールバックするオブジェクトを登録する。 observerと言っているが、実際には Delayer::Deferred::Worker を渡して利用している。 このメソッドはスレッドセーフです。

Args

observer

pushメソッドを備えているもの。引数に _@child_ の値が渡される

Return

self

# File lib/delayer/deferred/deferredable/chainable.rb, line 65
def add_child_observer(observer)
  change_sequence(:gaze) do
    @child_observer = observer
  end
  self
end
awaited() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 72
def awaited
  @awaited ||= [].freeze
end
cancel() click to toggle source

この一連のDeferredをこれ以上実行しない。 このメソッドはスレッドセーフです。

# File lib/delayer/deferred/deferredable/chainable.rb, line 33
def cancel
  change_sequence(:genocide) unless spoiled?
end
deferred(&proc)
Alias for: next
enter_pass() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 90
def enter_pass
  change_sequence(:pass)
end
error(&proc)
Alias for: trap
exit_pass() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 94
def exit_pass
  change_sequence(:resume)
end
has_awaited?() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 76
def has_awaited?
  not awaited.empty?
end
has_child?() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 37
def has_child?
  child ? true : false
end
next(&proc) click to toggle source

このDeferredが成功した場合の処理を追加する。 新しいDeferredのインスタンスを返す。 このメソッドはスレッドセーフです。 TODO: procが空のとき例外を発生させる

# File lib/delayer/deferred/deferredable/chainable.rb, line 17
def next(&proc)
  add_child(Delayer::Deferred::Chain::Next.new(&proc))
end
Also aliased as: deferred
reserve_activate() click to toggle source

activateメソッドを呼ぶDelayerジョブを登録する寸前に呼ばれる。

# File lib/delayer/deferred/deferredable/chainable.rb, line 86
def reserve_activate
  change_sequence(:reserve)
end
trap(&proc) click to toggle source

このDeferredが失敗した場合の処理を追加する。 新しいDeferredのインスタンスを返す。 このメソッドはスレッドセーフです。 TODO: procが空のとき例外を発生させる

# File lib/delayer/deferred/deferredable/chainable.rb, line 26
def trap(&proc)
  add_child(Delayer::Deferred::Chain::Trap.new(&proc))
end
Also aliased as: error

Protected Instance Methods

ancestor() click to toggle source

親を再帰的に辿り、一番最初のノードを返す。 親が複数見つかった場合は、それらを返す。

# File lib/delayer/deferred/deferredable/chainable.rb, line 102
def ancestor
  if @parent
    @parent.ancestor
  else
    self
  end
end
parent=(chainable) click to toggle source

cancelとかデバッグ用のコールグラフを得るために親を登録しておく。 add_childから呼ばれる。

# File lib/delayer/deferred/deferredable/chainable.rb, line 112
def parent=(chainable)
  @parent = chainable
end

Private Instance Methods

call_child_observer() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 118
def call_child_observer
  if has_child? and defined?(@child_observer)
    change_sequence(:called)
    @child_observer.push(@child)
  end
end
graph_mynode() click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 144
def graph_mynode
  if defined?(@seq_logger)
    label = "#{node_name}\n(#{@seq_logger.map(&:name).join('→')})"
  else
    label = "#{node_name}\n(#{sequence.name})"
  end
  "#{__id__} [shape=#{graph_shape},label=#{label.inspect}]"
end
node_name() click to toggle source

ノードの名前。サブクラスでオーバライドし、ノードが定義されたファイルの名前や行数などを入れておく。

# File lib/delayer/deferred/deferredable/chainable.rb, line 140
def node_name
  self.class.to_s
end
on_sequence_changed(old_seq, flow, new_seq) click to toggle source
# File lib/delayer/deferred/deferredable/chainable.rb, line 125
def on_sequence_changed(old_seq, flow, new_seq)
  case new_seq
  when NodeSequence::BURST_OUT
    call_child_observer
  when NodeSequence::GENOCIDE
    @parent.cancel if defined?(@parent) and @parent
  when NodeSequence::RESERVED_C, NodeSequence::RUN_C, NodeSequence::PASS_C, NodeSequence::AWAIT_C, NodeSequence::GRAFT_C
    if !has_child?
      notice "child: #{@child.inspect}"
      raise Delayer::Deferred::SequenceError.new("Sequence changed `#{old_seq.name}' to `#{flow}', but it has no child")
    end
  end
end