Class: Rbgo::Actor

Inherits:
Object
  • Object
show all
Defined in:
lib/rbgo/actor.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(&handler) ⇒ Actor

Returns a new instance of Actor.



26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rbgo/actor.rb', line 26

def initialize(&handler)
  self.handler           = handler
  @close_reason          = nil
  self.mail_box          = Queue.new
  self.once_for_msg_loop = Once.new
  self.once_for_close    = Once.new
  self.close_mutex       = ReentrantMutex.new

  self.children          = SyncSet.new
  self.linked_actors     = SyncSet.new
  self.supervisor_actors = SyncSet.new
end

Instance Attribute Details

#close_reasonObject (readonly)

Returns the value of attribute close_reason.



24
25
26
# File 'lib/rbgo/actor.rb', line 24

def close_reason
  @close_reason
end

#handlerObject

Returns the value of attribute handler.



23
24
25
# File 'lib/rbgo/actor.rb', line 23

def handler
  @handler
end

Instance Method Details

#close(reason = nil) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rbgo/actor.rb', line 52

def close(reason = nil)
  once_for_close.do do
    close_mutex.synchronize do
      @close_reason = reason
      mail_box.close
      mail_box.clear

      (parent&.send :children)&.delete(self)
      self.parent   = nil
      self.children = nil

      linked_actors.each do |l|
        CoRun::Routine.new(new_thread: false, queue_tag: :default) do
          l.close
        end
      end
      self.linked_actors = nil

      supervisor_actors.each do |sup|
        sup.send_msg(ActorClosedMsg.new(self)) rescue nil
      end
      self.supervisor_actors = nil

      nil
    end
  end
end

#closed?Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/rbgo/actor.rb', line 80

def closed?
  mail_box.closed?
end

#demonitor(actor) ⇒ Object



158
159
160
161
162
163
164
165
166
167
# File 'lib/rbgo/actor.rb', line 158

def demonitor(actor)
  return self if self.equal?(actor)
  close_mutex.synchronize do
    raise "can not demonitor from a closed actor" if closed?
    actor.send(:close_mutex).synchronize do
      actor.send(:supervisor_actors)&.delete(self)
    end
    self
  end
end


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rbgo/actor.rb', line 104

def link(actor)
  return self if self.equal?(actor)
  close_mutex.synchronize do
    raise "can not link from a closed actor" if closed?
    actor.send(:close_mutex).synchronize do
      if actor.closed?
        close
      else
        actor.send(:linked_actors).add(self)
        linked_actors.add(actor)
      end
    end
    self
  end
end

#monitor(actor) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rbgo/actor.rb', line 143

def monitor(actor)
  return self if self.equal?(actor)
  close_mutex.synchronize do
    raise "can not monitor from a closed actor" if closed?
    actor.send(:close_mutex).synchronize do
      if actor.closed?
        send_msg(ActorClosedMsg.new(actor))
      else
        actor.send(:supervisor_actors).add(self)
      end
    end
    self
  end
end

#send_children(msg) ⇒ Object



45
46
47
48
49
50
# File 'lib/rbgo/actor.rb', line 45

def send_children(msg)
  children.each do |child|
    child.send_msg(msg) rescue nil
  end
  self
end

#send_msg(msg) ⇒ Object



39
40
41
42
43
# File 'lib/rbgo/actor.rb', line 39

def send_msg(msg)
  mail_box << msg
  start_msg_loop
  self
end

#spawn_child(&handler) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/rbgo/actor.rb', line 84

def spawn_child(&handler)
  close_mutex.synchronize do
    raise "can not spawn from a closed actor" if closed?
    child = Actor.new(&handler)
    child.send :parent=, self
    children.add(child)
    child
  end
end


94
95
96
97
98
99
100
101
102
# File 'lib/rbgo/actor.rb', line 94

def spawn_link(&handler)
  close_mutex.synchronize do
    raise "can not spawn from a closed actor" if closed?
    l = spawn_child(&handler)
    l.send(:linked_actors).add(self)
    linked_actors.add(l)
    l
  end
end

#spawn_monitor(&handler) ⇒ Object



134
135
136
137
138
139
140
141
# File 'lib/rbgo/actor.rb', line 134

def spawn_monitor(&handler)
  close_mutex.synchronize do
    raise "can not spawn from a closed actor" if closed?
    m = spawn_child(&handler)
    m.send(:supervisor_actors).add(self)
    m
  end
end


120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rbgo/actor.rb', line 120

def unlink(actor)
  return self if self.equal?(actor)
  close_mutex.synchronize do
    raise "can not unlink from a closed actor" if closed?
    actor.send(:close_mutex).synchronize do
      unless actor.closed?
        actor.send(:linked_actors).delete(self)
      end
      linked_actors.delete(actor)
    end
    self
  end
end