Class: Celluloid::SyncCall

Inherits:
Call
  • Object
show all
Defined in:
lib/celluloid/calls.rb

Overview

Synchronous calls wait for a response

Instance Attribute Summary collapse

Attributes inherited from Call

#arguments, #block, #method

Instance Method Summary collapse

Methods inherited from Call

#check, #execute_block_on_receiver, #simulated_inspect_dump

Constructor Details

#initialize(sender, method, arguments = [], block = nil, task = Thread.current[:celluloid_task], chain_id = CallChain.current_id) ⇒ SyncCall

Returns a new instance of SyncCall.


69
70
71
72
73
74
75
# File 'lib/celluloid/calls.rb', line 69

def initialize(sender, method, arguments = [], block = nil, task = Thread.current[:celluloid_task], chain_id = CallChain.current_id)
  super(method, arguments, block)

  @sender   = sender
  @task     = task
  @chain_id = chain_id || Celluloid.uuid
end

Instance Attribute Details

#chain_idObject (readonly)

Returns the value of attribute chain_id


67
68
69
# File 'lib/celluloid/calls.rb', line 67

def chain_id
  @chain_id
end

#senderObject (readonly)

Returns the value of attribute sender


67
68
69
# File 'lib/celluloid/calls.rb', line 67

def sender
  @sender
end

#taskObject (readonly)

Returns the value of attribute task


67
68
69
# File 'lib/celluloid/calls.rb', line 67

def task
  @task
end

Instance Method Details

#cleanupObject


94
95
96
97
# File 'lib/celluloid/calls.rb', line 94

def cleanup
  exception = DeadActorError.new("attempted to call a dead actor")
  respond ErrorResponse.new(self, exception)
end

#dispatch(obj) ⇒ Object


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/celluloid/calls.rb', line 77

def dispatch(obj)
  CallChain.current_id = @chain_id
  result = super(obj)
  respond SuccessResponse.new(self, result)
rescue Exception => ex  # Exceptions that occur during synchronous calls are reraised in the
  # context of the sender

  respond ErrorResponse.new(self, ex)

  # Aborting indicates a protocol error on the part of the sender
  # It should crash the sender, but the exception isn't reraised
  # Otherwise, it's a bug in this actor and should be reraised
  raise unless ex.is_a?(AbortError)
ensure
  CallChain.current_id = nil
end

#respond(message) ⇒ Object


99
100
101
# File 'lib/celluloid/calls.rb', line 99

def respond(message)
  @sender << message
end

#responseObject


103
104
105
# File 'lib/celluloid/calls.rb', line 103

def response
  Celluloid.suspend(:callwait, self)
end

#valueObject


107
108
109
# File 'lib/celluloid/calls.rb', line 107

def value
  response.value
end

#waitObject


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/celluloid/calls.rb', line 111

def wait
  loop do
    message = Celluloid.mailbox.receive do |msg|
      msg.respond_to?(:call) and msg.call == self
    end

    if message.is_a?(SystemEvent)
      Thread.current[:celluloid_actor].handle_system_event(message)
    else
      # FIXME: add check for receiver block execution
      if message.respond_to?(:value)        # FIXME: disable block execution if on :sender and (exclusive or outside of task)
        # probably now in Call

        break message
      else
        message.dispatch
      end
    end
  end
end