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
- #receive(event, record: true) ⇒ Object
-
#redis_connection ⇒ Object
TODO protected?.
- #subscribe_for_commands(channel:) ⇒ Object
Class Method Details
.current ⇒ Object
133 134 135 |
# File 'lib/metacosm/simulation.rb', line 133 def self.current @current ||= new end |
Instance Method Details
#apply(command) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/metacosm/simulation.rb', line 41 def apply(command) mutex.synchronize do 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
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/metacosm/simulation.rb', line 57 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 = redis_connection redis.publish(@event_publication_channel, Marshal.dump(event_dto)) 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
137 138 139 140 |
# File 'lib/metacosm/simulation.rb', line 137 def clear! @events = [] @command_queue && @command_queue.clear end |
#command_queue ⇒ Object
12 13 14 |
# File 'lib/metacosm/simulation.rb', line 12 def command_queue @command_queue ||= Queue.new end |
#conduct! ⇒ Object
20 21 22 |
# File 'lib/metacosm/simulation.rb', line 20 def conduct! @conductor_thread = Thread.new { execute } end |
#construct_handler_for(command) ⇒ Object (protected)
148 149 150 151 152 153 154 155 |
# File 'lib/metacosm/simulation.rb', line 148 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)
162 163 164 165 166 |
# File 'lib/metacosm/simulation.rb', line 162 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
116 117 118 |
# File 'lib/metacosm/simulation.rb', line 116 def disable_local_events @local_events_disabled = true end |
#event_queue ⇒ Object
16 17 18 |
# File 'lib/metacosm/simulation.rb', line 16 def event_queue @event_queue ||= Queue.new end |
#events ⇒ Object
129 130 131 |
# File 'lib/metacosm/simulation.rb', line 129 def events @events ||= [] end |
#execute ⇒ Object
24 25 26 27 28 29 30 31 |
# File 'lib/metacosm/simulation.rb', line 24 def execute while true if (command=command_queue.pop) apply(command) end Thread.pass end end |
#fire(command) ⇒ Object
8 9 10 |
# File 'lib/metacosm/simulation.rb', line 8 def fire(command) command_queue.push(command) end |
#halt! ⇒ Object
33 34 35 |
# File 'lib/metacosm/simulation.rb', line 33 def halt! @conductor_thread.terminate end |
#handler_for(command) ⇒ Object (protected)
143 144 145 146 |
# File 'lib/metacosm/simulation.rb', line 143 def handler_for(command) @handlers ||= {} @handlers[command.self_class_name] ||= construct_handler_for(command) end |
#listener_for(event) ⇒ Object (protected)
157 158 159 160 |
# File 'lib/metacosm/simulation.rb', line 157 def listener_for(event) @listeners ||= {} @listeners[event.self_class_name] ||= construct_listener_for(event) end |
#local_events_disabled? ⇒ Boolean
120 121 122 |
# File 'lib/metacosm/simulation.rb', line 120 def local_events_disabled? @local_events_disabled ||= false end |
#mutex ⇒ Object
37 38 39 |
# File 'lib/metacosm/simulation.rb', line 37 def mutex @mutex = Mutex.new end |
#on_event(publish_to: nil, &blk) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/metacosm/simulation.rb', line 79 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 |
#receive(event, record: true) ⇒ Object
124 125 126 127 |
# File 'lib/metacosm/simulation.rb', line 124 def receive(event, record: true) events.push(event) if record apply_event(event) end |
#redis_connection ⇒ Object
TODO protected?
4 5 6 |
# File 'lib/metacosm/simulation.rb', line 4 def redis_connection Redis.new end |
#subscribe_for_commands(channel:) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/metacosm/simulation.rb', line 89 def subscribe_for_commands(channel:) p [ :subscribe_to_command_channel, channel: channel ] @command_subscription_thread = Thread.new do redis = redis_connection begin redis.subscribe(channel) do |on| on.subscribe do |chan, subscriptions| puts "Subscribed to ##{chan} (#{subscriptions} subscriptions)" end on. do |chan, | puts "##{chan}: #{}" apply(Marshal.load()) 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 |