Class: LiveResource::ResourceProxy

Inherits:
Object
  • Object
show all
Includes:
LogHelper
Defined in:
lib/live_resource/resource_proxy.rb

Overview

Client object that represents a resource, allowing method calls and getting/setting attributes. Typically these are returned from LiveResource finder methods (all, find, etc).

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from LogHelper

#logger, #logger=

Constructor Details

#initialize(redis_class, redis_name) ⇒ ResourceProxy

Create a new proxy given its Redis class and name; typically NOT USED by client code – use methods of LiveResource::Finders instead.



19
20
21
22
23
24
25
# File 'lib/live_resource/resource_proxy.rb', line 19

def initialize(redis_class, redis_name)
  @redis_class = redis_class
  @redis_name = redis_name
  @redis = RedisClient.new(redis_class, redis_name)
  @remote_methods = @redis.registered_methods
  @remote_attributes = @redis.registered_attributes
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *params, &block) ⇒ Object

Proxies attribute and remote method calls to the back-end provider.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/live_resource/resource_proxy.rb', line 28

def method_missing(m, *params, &block)
  # Strip trailing ?, ! for seeing if we support method
  sm = m.to_s.sub(/[!,?]$/, '').to_sym

  if @remote_attributes.include?(m)
    # Attribute get/set
    if m.match(/\=$/)
      m = m.to_s.sub(/\=$/, '').to_sym # Strip trailing equal

      remote_attribute_write(m, *params)
    else
      remote_attribute_read(m)
    end
  elsif @remote_methods.include?(sm)
    # Method call
    method = RemoteMethod.new(
                          :method => sm,
                          :params => params)

    if m.match(/!$/)
      # Async call, discard result
      method.flags[:discard_result] = true

      remote_send method
    elsif m.match(/\?$/)
      # Async call with future
      method = remote_send method
      Future.new(self, method)
    else
      # Synchronous method call
      wait_for_done remote_send(method)
    end
  else
    super
  end
end

Instance Attribute Details

#redis_classObject (readonly)

Returns the value of attribute redis_class.



14
15
16
# File 'lib/live_resource/resource_proxy.rb', line 14

def redis_class
  @redis_class
end

#redis_nameObject (readonly)

Returns the value of attribute redis_name.



14
15
16
# File 'lib/live_resource/resource_proxy.rb', line 14

def redis_name
  @redis_name
end

Instance Method Details

#done_with?(method) ⇒ Boolean

Check if remote method is already complete. May be called multiple times.

Parameters:

Returns:

  • (Boolean)


111
112
113
# File 'lib/live_resource/resource_proxy.rb', line 111

def done_with?(method)
  @redis.method_done_with? method
end

#encode_with(coder) ⇒ Object

Specify custom format when YAML encoding



137
138
139
140
141
# File 'lib/live_resource/resource_proxy.rb', line 137

def encode_with coder
  coder.tag = '!live_resource:resource'
  coder['class'] = @redis_class
  coder['name'] = @redis_name
end

#inspectObject



132
133
134
# File 'lib/live_resource/resource_proxy.rb', line 132

def inspect
  "#{self.class}: #{@redis_class} #{@redis_name}"
end

#remote_attribute_read(key, options = {}) ⇒ Object

Reads remote attribute.

Parameters:

  • key (Symbol)

    attribute name

Returns:

  • (Object)

    remote attribute value



119
120
121
# File 'lib/live_resource/resource_proxy.rb', line 119

def remote_attribute_read(key, options = {})
  @redis.attribute_read(key, options)
end

#remote_attribute_write(key, value, options = {}) ⇒ Object

Writes remote attribute to new value.

Parameters:

  • key (Symbol)

    attribute name

  • value (Object)

    new value for attribute

Returns:

  • new value for attribute



128
129
130
# File 'lib/live_resource/resource_proxy.rb', line 128

def remote_attribute_write(key, value, options = {})
  @redis.attribute_write(key, value, options)
end

#remote_send(method) ⇒ Object

Send a already-created method object; not typically used by clients – use method_missing interface instead.

Parameters:



80
81
82
# File 'lib/live_resource/resource_proxy.rb', line 80

def remote_send(method)
  @redis.method_send method
end

#respond_to_missing?(method, include_private) ⇒ Boolean

Checks if method is a supported attribute or remote method.

Parameters:

Returns:

  • (Boolean)


69
70
71
72
73
74
# File 'lib/live_resource/resource_proxy.rb', line 69

def respond_to_missing?(method, include_private)
  stripped_method = method.to_s.sub(/[!,?]$/, '').to_sym

  @remote_methods.include?(stripped_method) or
    @remote_attributes.include?(method)
end

#wait_for_done(method, timeout = 0) ⇒ Object

Wait for method to finish, blocks if method not complete. An exception raised by the remote resource will be captured and raised in the client’s thread. Clients may only wait once for completion.

Parameters:

  • method (LiveResource::RemoteMethod)

    method to wait for

  • timeout (Numeric) (defaults to: 0)

    seconds to wait for method completion



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/live_resource/resource_proxy.rb', line 91

def wait_for_done(method, timeout = 0)
  result = @redis.method_wait_for_result(method, timeout)

  if result.is_a?(Exception)
    # Merge the backtrace from the passed exception with this
    # stack trace so the final backtrace looks like the method_sender
    # called the method_provider directly.
    # trace = merge_backtrace caller, result.backtrace
    # result.set_backtrace trace

    result.set_backtrace result.backtrace
    raise result
  else
    result
  end
end