Class: RailsBridge::ContentBridge

Inherits:
Object
  • Object
show all
Defined in:
lib/rails_bridge/content_bridge.rb

Overview

ContentBridge

An abstraction for embedding content from a remote application within a Rails request.

Constant Summary collapse

DEFAULT_CONTENT =

Class Constants

'Remote Content Unavailable'
DEFAULT_REQUEST_TIMEOUT =

miliseconds

2000
DEFAULT_CACHE_TIMEOUT =
0
@@content_requests =
{}

Class Method Summary collapse

Class Method Details

.cache_get(key) ⇒ Object



46
47
48
49
# File 'lib/rails_bridge/content_bridge.rb', line 46

def cache_get key
  logger.debug "get key: #{key}"
  content = self.cache.fetch(key, :race_condition_ttl=>5.seconds)
end

.cache_set(key, content, expires_in) ⇒ Object



41
42
43
44
# File 'lib/rails_bridge/content_bridge.rb', line 41

def cache_set key, content, expires_in
  logger.debug "set key: #{key}"
  self.cache.write( key, content, :expires_in=>expires_in )
end

.cia_on_sucessObject



32
# File 'lib/rails_bridge/content_bridge.rb', line 32

alias :cia_on_sucess :on_success

.content_request(name, options = {}) {|new_request| ... } ⇒ Object

Yields:

  • (new_request)


128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/rails_bridge/content_bridge.rb', line 128

def content_request name, options={}
  raise "name must be a symbol" unless name.is_a? Symbol
  begin
    raise "WARNING: Already defined content_request '#{name}'" if @@content_requests.key?( name )
  rescue
    logger.warn $!.message
    logger.warn $!.backtrace * "\n"
  end
  new_request = ContentRequest.new options
  yield new_request if block_given?
  @@content_requests[name] = new_request
  new_request.content_bridge = self
  new_request
end

.content_requestsObject

custom accessor methods



30
# File 'lib/rails_bridge/content_bridge.rb', line 30

def content_requests; @@content_requests; end

.execute_requestsObject



114
115
116
117
# File 'lib/rails_bridge/content_bridge.rb', line 114

def execute_requests
  hydra = Typhoeus::Hydra.hydra # the singleton Hydra
  hydra.run
end

.get_content_request_from_remote(remote) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rails_bridge/content_bridge.rb', line 51

def get_content_request_from_remote( remote )
  if remote.is_a? Symbol
    raise "Undefined content_request :#{remote}" unless remote = @@content_requests[remote]
  end
  if remote.is_a? Hash
    remote = RailsBridge::ContentRequest.new remote
    remote.content_bridge = self
  elsif remote.is_a? String
    remote = RailsBridge::ContentRequest.new(:url=>remote)
    remote.content_bridge = self
  elsif !remote.is_a? RailsBridge::ContentRequest
    raise "Unexpected remote type: #{remote.class}"
  end
  remote
end

.get_merged_options(content_request, options) ⇒ Object

collect options by precedence



68
69
70
71
72
73
74
75
# File 'lib/rails_bridge/content_bridge.rb', line 68

def get_merged_options( content_request, options )
  options[:params]          =   content_request.params.merge( options[:params] || {} )
  options[:request_timeout] ||= content_request.request_timeout || self.request_timeout
  options[:cache_timeout]   ||= content_request.cache_timeout || self.cache_timeout
  options[:on_success]      ||= content_request.on_success || self.on_success
  options[:default_content] ||= content_request.default_content || self.default_content
  options
end

.get_remote_content(remote, options = {}) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/rails_bridge/content_bridge.rb', line 119

def get_remote_content( remote, options={} )
  result = nil
  request_remote_content( remote, options ) do |r_result|
    result = r_result
  end
  execute_requests
  result
end

.method_missing(method, *args, &block) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rails_bridge/content_bridge.rb', line 143

def method_missing method, *args, &block
  if matches = method.to_s.match( /^get_(.*)$/ )
    request_name = matches[1]
    self.get_remote_content( request_name.to_sym, *args )
  elsif matches = method.to_s.match( /^request_(.*)$/ )
    request_name = matches[1]
    self.request_remote_content( request_name.to_sym, *args, &block )
  else
    super
  end
end

.on_successObject



33
34
35
36
37
38
39
# File 'lib/rails_bridge/content_bridge.rb', line 33

def on_success
  if block_given?
    self.on_success= Proc.new
  else
    self.cia_on_sucess
  end
end

.request_remote_content(remote, options = {}, &block) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rails_bridge/content_bridge.rb', line 77

def request_remote_content( remote, options={}, &block )
  content_request = get_content_request_from_remote( remote )
  options = get_merged_options( content_request, options )
  
  # convert options for Typhoeus
  options[:timeout] =   options.delete(:request_timeout)  # Rename the request timeout param for Typhoeus
  on_success_proc = options.delete(:on_success)
  default_content = options.delete(:default_content)
  
  # options[:verbose] = true # for debugging only

  request = Typhoeus::Request.new(content_request.url, options)
  if self.cache && request.cache_timeout && request.cache_timeout > 0 && result = cache_get( request.cache_key )
    block.call(result)
  else
    result = default_content
    request.on_complete do |response|
      case response.code
      when 200
        result = response.body
        result = on_success_proc.call(result) if on_success_proc
        cache_set( request.cache_key, result, request.cache_timeout ) if self.cache && request.cache_timeout && request.cache_timeout > 0
        logger.debug "ContentBridge : Request Succeeded - Content: #{result}"
      when 0
        logger.warn "ContentBridge : Request Timeout for #{content_request.url}"
      else
        logger.warn "ContentBridge : Request for #{content_request.url}\mRequest Failed with HTTP result code: #{response.code}\n#{response.body}"
      end
      block.call(result)
    end
    hydra = Typhoeus::Hydra.hydra # the singleton Hydra
    hydra.disable_memoization
    hydra.queue request
  end
  nil
end