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 methods 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.
257 258 259 260 261 |
# File 'lib/eventbox/boxable.rb', line 257 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.
263 264 265 |
# File 'lib/eventbox/boxable.rb', line 263 def event_loop @event_loop end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
255 256 257 |
# File 'lib/eventbox/boxable.rb', line 255 def name @name end |
Instance Method Details
#abort ⇒ Object
Send a AbortAction to the running thread.
287 288 289 |
# File 'lib/eventbox/boxable.rb', line 287 def abort @thread.raise AbortAction end |
#current? ⇒ Boolean
Belongs the current thread to this action.
292 293 294 |
# File 'lib/eventbox/boxable.rb', line 292 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
.
275 276 277 278 279 280 281 282 283 284 |
# File 'lib/eventbox/boxable.rb', line 275 def raise(*args) 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 |