Sha256: e4c40ae4af7f2bb1d54e2f1eaea8fce5c80d78ba1c4cf44cbb8158a0c9eb9b84

Contents?: true

Size: 1.85 KB

Versions: 1

Compression:

Stored size: 1.85 KB

Contents

require 'thread'

require 'concurrent/global_thread_pool'

module Concurrent

  IllegalMethodCallError = Class.new(StandardError)

  class Defer
    include UsesGlobalThreadPool

    def initialize(opts = {}, &block)
      operation = opts[:op] || opts[:operation]
      @callback = opts[:cback] || opts[:callback]
      @errorback = opts[:eback] || opts[:error] || opts[:errorback]
      thread_pool = opts[:pool] || opts[:thread_pool]

      raise ArgumentError.new('no operation given') if operation.nil? && ! block_given?
      raise ArgumentError.new('two operations given') if ! operation.nil? && block_given?

      @operation = operation || block

      if operation.nil?
        @running = false
      else
        self.go
      end
    end

    def then(&block)
      raise IllegalMethodCallError.new('a callback has already been provided') unless @callback.nil?
      raise IllegalMethodCallError.new('the defer is already running') if @running
      raise ArgumentError.new('no block given') unless block_given?
      @callback = block
      return self
    end

    def rescue(&block)
      raise IllegalMethodCallError.new('a errorback has already been provided') unless @errorback.nil?
      raise IllegalMethodCallError.new('the defer is already running') if @running
      raise ArgumentError.new('no block given') unless block_given?
      @errorback = block
      return self
    end
    alias_method :catch, :rescue
    alias_method :on_error, :rescue

    def go
      return nil if @running
      @running = true
      Defer.thread_pool.post { fulfill }
      return nil
    end

    private

    # @private
    def fulfill # :nodoc:
      result = @operation.call
      @callback.call(result) unless @callback.nil?
    rescue Exception => ex
      @errorback.call(ex) unless @errorback.nil?
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
concurrent-ruby-0.2.1 lib/concurrent/defer.rb