class Elevate::IOCoordinator

Implements task cancellation.

Compliant I/O mechanisms (such as HTTP requests) register long-running operations with a well-known instance of this class. When a cancellation request is received from another thread, the long-running operation is cancelled.

Public Class Methods

for_thread() click to toggle source

Retrieves the current IOCoordinator for this thread.

@return [IOCoordinator,nil]

IOCoordinator previously installed to this thread

@api public

# File lib/elevate/io_coordinator.rb, line 15
def self.for_thread
  Thread.current[:io_coordinator]
end
new() click to toggle source

Initializes a new IOCoordinator with the default state.

@api private

# File lib/elevate/io_coordinator.rb, line 22
def initialize
  @lock = NSLock.alloc.init
  @blocking_operation = nil
  @cancelled = false
  @exception_class = nil
end

Public Instance Methods

cancel(exception_class = CancelledError) click to toggle source

Cancels the I/O operation (if any), raising an exception of type exception_class in the worker thread.

If the thread is not currently blocked, then set a flag requesting cancellation.

@return [void]

@api private

# File lib/elevate/io_coordinator.rb, line 37
def cancel(exception_class = CancelledError)
  blocking_operation = nil

  @lock.lock
  @cancelled = true
  @exception_class = exception_class
  blocking_operation = @blocking_operation
  @lock.unlock

  if blocking_operation
    blocking_operation.cancel
  end
end
cancelled?() click to toggle source

Returns the cancelled flag.

@return [Boolean]

true if this coordinator has been +cancel+ed previously.

@api private

# File lib/elevate/io_coordinator.rb, line 57
def cancelled?
  cancelled = nil

  @lock.lock
  cancelled = @cancelled
  @lock.unlock

  cancelled
end
install() click to toggle source

Installs this IOCoordinator to a well-known thread-local.

@return [void]

@api private

# File lib/elevate/io_coordinator.rb, line 72
def install
  Thread.current[:io_coordinator] = self
end
signal_blocked(operation) click to toggle source

Marks the specified operation as one that will potentially block the worker thread for a significant amount of time.

@param operation [#cancel]

operation responsible for blocking

@return [void]

@api public

# File lib/elevate/io_coordinator.rb, line 85
def signal_blocked(operation)
  check_for_cancellation

  @lock.lock
  @blocking_operation = operation
  @lock.unlock
end
signal_unblocked(operation) click to toggle source

Signals that the specified operation has completed, and is no longer responsible for blocking the worker thread.

@return [void]

@api public

# File lib/elevate/io_coordinator.rb, line 99
def signal_unblocked(operation)
  @lock.lock
  @blocking_operation = nil
  @lock.unlock

  check_for_cancellation
end
uninstall() click to toggle source

Removes the thread-local for the calling thread.

@return [void]

@api private

# File lib/elevate/io_coordinator.rb, line 112
def uninstall
  Thread.current[:io_coordinator] = nil
end

Private Instance Methods

check_for_cancellation() click to toggle source
# File lib/elevate/io_coordinator.rb, line 118
def check_for_cancellation
  raise @exception_class if cancelled?
end