Class: FlowMonitor::Controller
- Inherits:
-
Object
- Object
- FlowMonitor::Controller
- Defined in:
- lib/libcfruby/flowmonitor.rb
Overview
The Controller class provides an encapsulation and message passing mechanism that can be used to add fine-grained flow control and logging facilities to a library. For general use a library defines one or more Controller objects that calling programs register Observer (interface) objects to. The observers are called in order of registration and are told, via Message objects, what the library intends to do at a given point, as well as given a chance to override the action.
Instance Method Summary collapse
-
#attempt(intention, *tags, &block) ⇒ Object
attempt is called with an intention str, a list of tags, and a code block which, if run, would carry out the intention.
-
#attempt_abort(reason = "no reason given") ⇒ Object
helper method to make it easier to understand the attempt flow control.
-
#build_message(type, message, *tags) ⇒ Object
builds a message object from the given components.
-
#exception(message, *tags) ⇒ Object
A helper function to send an exception message.
-
#inform(level, message, *tags) ⇒ Object
A helper function to send a simple informative message with a named level.
-
#initialize ⇒ Controller
constructor
A new instance of Controller.
-
#register(observer) ⇒ Object
registers the observer with this Controller.
-
#send_message(message) ⇒ Object
sends a message to all the registered observers until one of them returns false or all of them have been sent.
-
#unregister(observer) ⇒ Object
Unregisters a listening observer.
-
#unregister_all ⇒ Object
Clears all listening observers.
Constructor Details
#initialize ⇒ Controller
Returns a new instance of Controller.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/libcfruby/flowmonitor.rb', line 30 def initialize() # Array to hold registered observers @observers = Array.new() # simple mutex for handling multi-threaded access. NOTE: the mutex is # currently only used to handle registering and unregistering observers. # To avoid overhead messages are sent without the aid of the mutex. This # could mean that an unregistered observer *could* get an extra message or # two from another thread during the unregistering process. @mutex = Mutex.new() end |
Instance Method Details
#attempt(intention, *tags, &block) ⇒ Object
attempt is called with an intention str, a list of tags, and a code block which, if run, would carry out the intention. The intention and the tags are bundled into a Message object and passed, in order, to any listening Observer objects, which may then abort the block. If all the listening Observers allow, the block is run and is assumed successful unless an Exception is raised. Exceptions raised are first passed as a message to the Observer and are then allowed to bubble up through their normal paths.
83 84 85 86 87 88 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 115 116 117 118 119 120 |
# File 'lib/libcfruby/flowmonitor.rb', line 83 def attempt(intention, *, &block) .flatten! if(!.kind_of?(Array)) = Array.[]() end # build the message object if((('intention', "#{intention} - attempt", ))) done = false reason = catch(:attemptabort) { begin yield(block) rescue Exception exception("Error handling attempt \"#{intention}\" - #{$!.to_s}", ['error', 'attempt']) # we've passed it on, re-raise it raise($!) end << 'attempt' << 'attemptdone' inform('info', "#{intention} - done", ) done = true } # if we bailed we should send a message explaining why if(!done) if(!reason) reason = "no reason given" end << 'attempt' << 'attemptabort' inform('debug', "#{intention} - aborted - #{reason}", ) end else << 'attempt' << 'attemptpreempt' inform('verbose', "#{intention} - pre-empted", ) end end |
#attempt_abort(reason = "no reason given") ⇒ Object
helper method to make it easier to understand the attempt flow control. Causes an attempt to preemptively return with an optional message. May do unpredicatable and unpleasant things if called outside of an attempt
block.
126 127 128 |
# File 'lib/libcfruby/flowmonitor.rb', line 126 def attempt_abort(reason="no reason given") throw(:attemptabort, reason) end |
#build_message(type, message, *tags) ⇒ Object
builds a message object from the given components
149 150 151 152 153 154 155 156 157 |
# File 'lib/libcfruby/flowmonitor.rb', line 149 def (type, , *) .flatten! = Message.new(type, ) .each() { |t| .add_tag(t) } return() end |
#exception(message, *tags) ⇒ Object
A helper function to send an exception message
139 140 141 142 143 144 145 |
# File 'lib/libcfruby/flowmonitor.rb', line 139 def exception(, *) .flatten! if(!.include?('error')) << 'error' end (('exception', , )) end |
#inform(level, message, *tags) ⇒ Object
A helper function to send a simple informative message with a named level
132 133 134 135 |
# File 'lib/libcfruby/flowmonitor.rb', line 132 def inform(level, , *) .flatten! ((level.to_s, , )) end |
#register(observer) ⇒ Object
registers the observer with this Controller. observer is expected to implement the Observer interface.
45 46 47 48 49 50 51 52 53 |
# File 'lib/libcfruby/flowmonitor.rb', line 45 def register(observer) if(!observer.respond_to?(:handle_message)) raise(FlowControllerInterfaceError, "observer does not implement a message_handler method") end @mutex.synchronize { @observers << observer } end |
#send_message(message) ⇒ Object
sends a message to all the registered observers until one of them returns false or all of them have been sent. Returns false if any observer returns false or true if it sends the message to all of them without receiving a false in return.
163 164 165 166 167 168 169 170 171 |
# File 'lib/libcfruby/flowmonitor.rb', line 163 def () @observers.each() { |observer| if(observer.() == false) return(false) end } return(true) end |
#unregister(observer) ⇒ Object
Unregisters a listening observer
57 58 59 60 61 62 63 64 65 |
# File 'lib/libcfruby/flowmonitor.rb', line 57 def unregister(observer) @mutex.synchronize { @observers.each_index() { |i| if(@observers[i] === observer) @observers.delete_at(i) end } } end |
#unregister_all ⇒ Object
Clears all listening observers
69 70 71 72 73 |
# File 'lib/libcfruby/flowmonitor.rb', line 69 def unregister_all() @mutex.synchronize() { @observers = Array.new() } end |