Class: Eventbox::Action
- Inherits:
-
Object
- Object
- Eventbox::Action
- Defined in:
- lib/eventbox/boxable.rb
Overview
An Action object is thin wrapper for a Ruby thread.
It is returned by #action and optionally passed as last argument to action methods. It can be used to interrupt the program execution by an exception.
However in contrast to ruby’s builtin threads, any interruption must be explicit allowed. Exceptions raised to an action thread are delayed until a code block is reached which explicit allows interruption. The only exception which is delivered to the action thread by default is AbortAction. It is raised by #shutdown! and is delivered as soon as a blocking operation is executed.
An Action object can be used to stop the action while blocking operations. It should be made sure, that the ‘rescue` statement is outside of the block to `handle_interrupt`. Otherwise it could happen, that the rescuing code is interrupted by the signal. Sending custom signals to an action works like:
class MySignal < Interrupt
end
async_call def init
a = start_sleep
a.raise(MySignal)
end
action def start_sleep
Thread.handle_interrupt(MySignal => :on_blocking) do
sleep
end
rescue MySignal
puts "well-rested"
end
Instance Attribute Summary collapse
-
#event_loop ⇒ Object
readonly
private
Returns the value of attribute event_loop.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
-
#abort ⇒ Object
Send a AbortAction to the running thread.
-
#current? ⇒ Boolean
Belongs the current thread to this action.
-
#initialize(name, thread, event_loop) ⇒ Action
constructor
A new instance of Action.
-
#raise(*args) ⇒ Object
Send a signal to the running action.
Constructor Details
#initialize(name, thread, event_loop) ⇒ Action
Returns a new instance of Action.
253 254 255 256 257 |
# File 'lib/eventbox/boxable.rb', line 253 def initialize(name, thread, event_loop) @name = name @thread = thread @event_loop = event_loop end |
Instance Attribute Details
#event_loop ⇒ Object (readonly, private)
Returns the value of attribute event_loop.
259 260 261 |
# File 'lib/eventbox/boxable.rb', line 259 def event_loop @event_loop end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
251 252 253 |
# File 'lib/eventbox/boxable.rb', line 251 def name @name end |
Instance Method Details
#abort ⇒ Object
Send a AbortAction to the running thread.
284 285 286 |
# File 'lib/eventbox/boxable.rb', line 284 def abort @thread.raise AbortAction end |
#current? ⇒ Boolean
Belongs the current thread to this action.
289 290 291 |
# File 'lib/eventbox/boxable.rb', line 289 def current? @thread.respond_to?(:current?) ? @thread.current? : (@thread == Thread.current) end |
#raise(*args) ⇒ Object
Send a signal to the running action.
The signal must be kind of Exception. See Eventbox::Action about asynchronous delivery of signals.
This method does nothing if the action is already finished.
If #raise is called within the action (#current? returns ‘true`), all exceptions are delivered immediately. This happens regardless of the current interrupt mask set by `Thread.handle_interrupt`.
271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/eventbox/boxable.rb', line 271 def raise(*args) # ignore raise, if sent from the action thread if AbortAction === args[0] || (Module === args[0] && args[0].ancestors.include?(AbortAction)) ::Kernel.raise InvalidAccess, "Use of Eventbox::AbortAction is not allowed - use Action#abort or a custom exception subclass" end if @event_loop.event_scope? args = Sanitizer.sanitize_values(args, @event_loop, nil) end @thread.raise(*args) end |