Class: Metacosm::Simulation
- Inherits:
-
Object
- Object
- Metacosm::Simulation
- Defined in:
- lib/metacosm/simulation.rb
Direct Known Subclasses
Class Method Summary collapse
Instance Method Summary collapse
- #apply(command) ⇒ Object
- #apply_event(event) ⇒ Object
- #clear! ⇒ Object
- #command_queue ⇒ Object
- #conduct! ⇒ Object
- #construct_handler_for(command) ⇒ Object protected
- #construct_listener_for(event) ⇒ Object protected
- #disable_local_events ⇒ Object
- #event_queue ⇒ Object
- #events ⇒ Object
- #execute ⇒ Object
- #fire(command) ⇒ Object
- #halt! ⇒ Object
- #handler_for(command) ⇒ Object protected
- #listener_for(event) ⇒ Object protected
- #local_events_disabled? ⇒ Boolean
- #mutex ⇒ Object
- #on_event(publish_to: nil, &blk) ⇒ Object
-
#params ⇒ Object
TODO protected? def redis_connection Redis.new end.
- #receive(event, record: true) ⇒ Object
- #received_commands ⇒ Object
- #subscribe_for_commands(channel:) ⇒ Object
Class Method Details
.current ⇒ Object
147 148 149 |
# File 'lib/metacosm/simulation.rb', line 147 def self.current @current ||= new end |
Instance Method Details
#apply(command) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/metacosm/simulation.rb', line 45 def apply(command) mutex.synchronize do received_commands.push(command) if command.is_a?(Hash) handler_module_name = command.delete(:handler_module) handler_class_name = command.delete(:handler_class_name) module_name = handler_module_name handler = (module_name.constantize). const_get(handler_class_name).new handler.handle(command) else handler = handler_for(command) handler.handle(command.attrs) end end end |
#apply_event(event) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/metacosm/simulation.rb', line 67 def apply_event(event) if !@on_event_callback.nil? event_dto = event.attrs.merge(listener_module: event.listener_module_name, listener_class_name: event.listener_class_name) @on_event_callback[event_dto] end if !@event_publication_channel.nil? event_dto = event.attrs.merge(listener_module: event.listener_module_name, listener_class_name: event.listener_class_name) REDIS_PUB.with do |redis| redis.publish(@event_publication_channel, Marshal.dump(event_dto)) end end if !local_events_disabled? listener = listener_for(event) if event.attrs.any? listener.receive(event.attrs) else listener.receive end end end |
#clear! ⇒ Object
151 152 153 154 |
# File 'lib/metacosm/simulation.rb', line 151 def clear! @events = [] @command_queue && @command_queue.clear end |
#command_queue ⇒ Object
16 17 18 |
# File 'lib/metacosm/simulation.rb', line 16 def command_queue @command_queue ||= Queue.new end |
#conduct! ⇒ Object
24 25 26 |
# File 'lib/metacosm/simulation.rb', line 24 def conduct! @conductor_thread = Thread.new { execute } end |
#construct_handler_for(command) ⇒ Object (protected)
162 163 164 165 166 167 168 169 |
# File 'lib/metacosm/simulation.rb', line 162 def construct_handler_for(command) module_name = command.handler_module_name (module_name.constantize). const_get(command.handler_class_name).new rescue => ex binding.pry raise ex end |
#construct_listener_for(event) ⇒ Object (protected)
176 177 178 179 180 |
# File 'lib/metacosm/simulation.rb', line 176 def construct_listener_for(event) module_name = event.listener_module_name listener = (module_name.constantize).const_get(event.listener_class_name).new(self) listener end |
#disable_local_events ⇒ Object
130 131 132 |
# File 'lib/metacosm/simulation.rb', line 130 def disable_local_events @local_events_disabled = true end |
#event_queue ⇒ Object
20 21 22 |
# File 'lib/metacosm/simulation.rb', line 20 def event_queue @event_queue ||= Queue.new end |
#events ⇒ Object
143 144 145 |
# File 'lib/metacosm/simulation.rb', line 143 def events @events ||= [] end |
#execute ⇒ Object
28 29 30 31 32 33 34 35 |
# File 'lib/metacosm/simulation.rb', line 28 def execute while true if (command=command_queue.pop) apply(command) end Thread.pass end end |
#fire(command) ⇒ Object
12 13 14 |
# File 'lib/metacosm/simulation.rb', line 12 def fire(command) command_queue.push(command) end |
#halt! ⇒ Object
37 38 39 |
# File 'lib/metacosm/simulation.rb', line 37 def halt! @conductor_thread.terminate end |
#handler_for(command) ⇒ Object (protected)
157 158 159 160 |
# File 'lib/metacosm/simulation.rb', line 157 def handler_for(command) @handlers ||= {} @handlers[command.self_class_name] ||= construct_handler_for(command) end |
#listener_for(event) ⇒ Object (protected)
171 172 173 174 |
# File 'lib/metacosm/simulation.rb', line 171 def listener_for(event) @listeners ||= {} @listeners[event.self_class_name] ||= construct_listener_for(event) end |
#local_events_disabled? ⇒ Boolean
134 135 136 |
# File 'lib/metacosm/simulation.rb', line 134 def local_events_disabled? @local_events_disabled ||= false end |
#mutex ⇒ Object
41 42 43 |
# File 'lib/metacosm/simulation.rb', line 41 def mutex @mutex = Mutex.new end |
#on_event(publish_to: nil, &blk) ⇒ Object
90 91 92 93 94 95 96 97 98 |
# File 'lib/metacosm/simulation.rb', line 90 def on_event(publish_to:nil,&blk) unless publish_to.nil? @event_publication_channel = publish_to end if block_given? @on_event_callback = blk end end |
#params ⇒ Object
TODO protected? def redis_connection Redis.new end
8 9 10 |
# File 'lib/metacosm/simulation.rb', line 8 def params @params ||= {} end |
#receive(event, record: true) ⇒ Object
138 139 140 141 |
# File 'lib/metacosm/simulation.rb', line 138 def receive(event, record: true) events.push(event) if record apply_event(event) end |
#received_commands ⇒ Object
63 64 65 |
# File 'lib/metacosm/simulation.rb', line 63 def received_commands @commands_received ||= [] end |
#subscribe_for_commands(channel:) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/metacosm/simulation.rb', line 100 def subscribe_for_commands(channel:) p [ :subscribe_to_command_channel, channel: channel ] @command_subscription_thread = Thread.new do REDIS_SUB.with do |redis| begin redis.subscribe(channel) do |on| on.subscribe do |chan, subscriptions| puts "Subscribed to ##{chan} (#{subscriptions} subscriptions)" end on. do |chan, | # puts "##{chan}: #{message}" command_data = Marshal.load() p [ :got_message, command_data: command_data ] apply(command_data) end on.unsubscribe do |chan, subscriptions| puts "Unsubscribed from ##{chan} (#{subscriptions} subscriptions)" end end rescue Redis::BaseConnectionError => error puts "#{error}, retrying in 1s" sleep 1 retry end end end end |