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[
 :marshal_load,
 :marshal_dump,
 :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,
]

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of PromiseProxy.



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

def initialize(promise_id, timeout, attr=nil)
  marshal_load([promise_id, timeout, attr])
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



89
90
91
92
93
# File 'lib/marty/promise_proxy.rb', line 89

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)


56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/marty/promise_proxy.rb', line 56

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 => exc
          @result = ::Delorean::Engine.grok_runtime_exception(exc)
        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



35
36
37
# File 'lib/marty/promise_proxy.rb', line 35

def __promise__
  @promise
end

#is_a?(c) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
# File 'lib/marty/promise_proxy.rb', line 39

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

#marshal_dumpObject



24
25
26
# File 'lib/marty/promise_proxy.rb', line 24

def marshal_dump
  [@promise.id, @timeout, @attr]
end

#marshal_load(args) ⇒ Object



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

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

#nested_under_indifferent_accessObject



48
49
50
# File 'lib/marty/promise_proxy.rb', line 48

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)


83
84
85
# File 'lib/marty/promise_proxy.rb', line 83

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