Class: Marty::PromiseProxy

Inherits:
BasicObject
Defined in:
lib/marty/promise_proxy.rb

Overview

Promise mechanism shamelessly stolen and modified from github.com/bhuga/promising-future/blob/master/lib/promise.rb

Constant Summary collapse

NOT_SET =
::Object.new.freeze
METH_SET =
::Set[
 :force,
 :__force__,
 # Added for Rails 4 -- were causing forced eval.
 # This list is very hacky and will depend on how
 # ActiveRecord treats assignment to proxy objs.
 :is_a?,
 :nested_under_indifferent_access,
 :as_json,
]

Instance Method Summary collapse

Constructor Details

#initialize(promise_id, timeout, attr = nil) ⇒ PromiseProxy

Returns a new instance of PromiseProxy.



19
20
21
22
23
24
# File 'lib/marty/promise_proxy.rb', line 19

def initialize(promise_id, timeout, attr = nil)
  promise_id, @timeout, @attr = promise_id, timeout, attr
  @promise = ::Marty::Promise.find(promise_id)
  @mutex   = ::Mutex.new
  @result  = NOT_SET
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)



84
85
86
87
88
# File 'lib/marty/promise_proxy.rb', line 84

def method_missing(method, *args, &block)
  # ::File.open('/tmp/dj.out', 'a') { |f| f.puts "FORCE MISS #{method}" }

  __force__.__send__(method, *args, &block)
end

Instance Method Details

#__force__Object Also known as: force

Force the evaluation of this promise immediately

Returns:

  • (Object)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/marty/promise_proxy.rb', line 51

def __force__
  if @result.equal?(NOT_SET)
    @mutex.synchronize do
      if @result.equal?(NOT_SET)
        begin
          @result = @promise.wait_for_result(@timeout)
          @result = @result[@attr] if @attr && !@result['error']
        rescue ::Exception => e
          @result = ::Delorean::Engine.grok_runtime_exception(e)
        end
      end
    end
  end

  # FIXME: the logic for shape of exceptions from Delorean is spread
  # all over the place.
  @result.is_a?(::Hash) &&
    @result['error'] ? ::Kernel.raise(@result['error']) : @result
end

#__promise__Object



30
31
32
# File 'lib/marty/promise_proxy.rb', line 30

def __promise__
  @promise
end

#as_jsonObject



26
27
28
# File 'lib/marty/promise_proxy.rb', line 26

def as_json(*)
  { '__promise__' => [@promise.id, @timeout, @attr] }
end

#is_a?(_c) ⇒ Boolean

Returns:

  • (Boolean)


34
35
36
37
38
39
40
41
# File 'lib/marty/promise_proxy.rb', line 34

def is_a?(_c)
  # Marty::PromiseProxy == c
  # {}.is_a? c

  # FIXME: not sure why this has to return false.  Otherwise, some
  # spec tests fail.
  false
end

#nested_under_indifferent_accessObject



43
44
45
# File 'lib/marty/promise_proxy.rb', line 43

def nested_under_indifferent_access
  false
end

#respond_to?(method, include_all = false) ⇒ Boolean

Does this promise support the given method?

Parameters:

  • (Symbol)

Returns:

  • (Boolean)


78
79
80
# File 'lib/marty/promise_proxy.rb', line 78

def respond_to?(method, include_all = false)
  METH_SET.member?(method) || __force__.respond_to?(method, include_all)
end