lib/lvs/json_service/request.rb in LVS-JSONService-0.4.2 vs lib/lvs/json_service/request.rb in LVS-JSONService-0.4.3
- old
+ new
@@ -1,6 +1,7 @@
require 'json'
+require 'ostruct'
require 'lvs/json_service/logger'
require 'lvs/json_service/connection_manager'
module LVS
module JsonService
@@ -13,11 +14,11 @@
module ClassMethods
def unique_request_id
Digest::SHA1.hexdigest((rand(4294967295)+Time.now.usec).to_s)
end
- def http_request_with_timeout(service, args, options)
+ def http_standard_request_with_timeout(service, args, options)
uri = URI.parse(service)
req = Net::HTTP::Post.new(uri.path)
req.add_field("X-LVS-Request-ID", options[:request_id])
@@ -63,69 +64,123 @@
end
raise LVS::JsonService::BackendUnavailableError.new("Backend unavailable", 500, service, args)
rescue OpenSSL::SSL::SSLError => e
raise LVS::JsonService::BackendUnavailableError.new("Backend unavailable #{e}", 500, service, args)
-
end
if response.is_a?(Net::HTTPNotFound)
raise LVS::JsonService::NotFoundError.new("404 Found for the service #{service}", 404, service, args)
end
if response.is_a?(Net::HTTPNotModified)
raise LVS::JsonService::NotModified.new("304 Data hasn't changed", 304, service, args)
end
- response
+ yield(response)
end
+ def http_eventmachine_request_with_timeout(service, args, options)
+ http_options = {}
+ http_options[:timeout] = options[:timeout] || 1
+ http_options[:head] = {"X-LVS-Request-ID" => options[:request_id]}
+ http_options[:body] = {"object_request" => args.to_json}
+
+ http = EventMachine::HttpRequest.new(service).post(http_options)
+ http.callback {
+ response = OpenStruct.new(:request_id => http.response_header["X-LVS-Request-ID"], :body => http.response)
+ yield(response)
+ }
+ http.errback {
+ if (http.response_header.status == 404)
+ yield(LVS::JsonService::NotFoundError.new("404 Found for the service #{service}", 404, service, args))
+ elsif (http.response_header.status == 304)
+ yield(LVS::JsonService::NotModified.new("304 Data hasn't changed", 304, service, args))
+ elsif (http.response_header.status == 0)
+ yield(LVS::JsonService::BackendUnavailableError.new("Backend unavailable (in time)", 500, service, args))
+ else
+ yield(LVS::JsonService::Error.new("Unknown error (#{http.response_header.inspect})", 500, service, args))
+ end
+ }
+ end
+
def run_remote_request(service, args, options = {})
LVS::JsonService::Logger.debug "Requesting '#{service}' with #{args.to_json}"
+ response = nil
+ result = nil
options[:request_id] = unique_request_id
+
if options[:cached_for]
timing = "CACHED"
- response, result = Rails.cache.fetch([service, args].cache_key, :expires_in => options[:cached_for]) do
- start = Time.now
- response = http_request_with_timeout(service, args, options)
- verify_request_id(response, options[:request_id])
- net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
- start = Time.now
- result = JSON.parse(response.body)
- parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
- timing = "Net: #{net_timing}, Parse: #{parse_timing}"
- [response, result]
+ response, result = Rails.cache.read([service, args].cache_key, :expires_in => options[:cached_for])
+ end
+ if response.nil?
+ start = Time.now
+ if options[:eventmachine_async]
+ http_eventmachine_request_with_timeout(service, args, options) do |response|
+ if response.is_a?(LVS::JsonService::Error)
+ result = response
+ else
+ verify_request_id(response.request_id, options[:request_id])
+ net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
+ start = Time.now
+ result = JSON.parse(response.body)
+ parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
+ timing = "Net: #{net_timing}, Parse: #{parse_timing}"
+ if options[:cached_for]
+ Rails.cache.write([service, args].cache_key, [response, result], :expires_in => options[:cached_for])
+ end
+ log_response(timing, response.body, options)
+ if result.is_a?(Hash) && result.has_key?("PCode")
+ result = LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
+ end
+ end
+ yield(result) if block_given?
+ return result
+ end
+ else
+ http_standard_request_with_timeout(service, args, options) do |response|
+ verify_request_id(response["X-LVS-Request-ID"], options[:request_id])
+ net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
+ start = Time.now
+ result = JSON.parse(response.body)
+ parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
+ timing = "Net: #{net_timing}, Parse: #{parse_timing}"
+ if options[:cached_for]
+ Rails.cache.write([service, args].cache_key, [response, result], :expires_in => options[:cached_for])
+ end
+ log_response(timing, response.body, options)
+ if result.is_a?(Hash) && result.has_key?("PCode")
+ raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
+ end
+ yield(result) if block_given?
+ return result
+ end
end
else
- start = Time.now
- response = http_request_with_timeout(service, args, options)
- verify_request_id(response, options[:request_id])
- net_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
- start = Time.now
- result = JSON.parse(response.body)
- parse_timing = ("%.1f" % ((Time.now - start) * 1000)) + "ms"
- timing = "Net: #{net_timing}, Parse: #{parse_timing}"
+ log_response(timing, response.body, options)
+ if result.is_a?(Hash) && result.has_key?("PCode")
+ raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
+ end
end
+ result
+ end
- if response.body.size < 1024 || options[:debug]
- LVS::JsonService::Logger.debug "Response (#{timing}): #{response.body.gsub(/\n/, '')}"
+ def log_response(timing, body, options)
+ if body.size < 1024 || options[:debug]
+ LVS::JsonService::Logger.debug "Response (#{timing}): #{body.gsub(/\n/, '')}"
else
- LVS::JsonService::Logger.debug "Response Snippet (#{timing} / #{"%.1f" % (response.body.size/1024)}kB): #{response.body.gsub(/\n/, '')[0..1024]}"
+ LVS::JsonService::Logger.debug "Response Snippet (#{timing} / #{"%.1f" % (body.size/1024)}kB): #{body.gsub(/\n/, '')[0..1024]}"
end
- if result.is_a?(Hash) && result.has_key?("PCode")
- raise LVS::JsonService::Error.new(result["message"], result["PCode"], service, args, result)
- end
- result
end
- def verify_request_id(response, request_id)
- returned_request_id = response["X-LVS-Request-ID"]
- if returned_request_id != request_id && !returned_request_id.blank?
- raise LVS::JsonService::RequestMismatchError.new("The sent Request ID (#{request_id}) didn't " +
+ def verify_request_id(returned_request_id, sent_request_id)
+ if returned_request_id != sent_request_id && !returned_request_id.blank?
+ raise LVS::JsonService::RequestMismatchError.new("The sent Request ID (#{sent_request_id}) didn't " +
"match the returned Request ID (#{returned_request_id}) ")
else
- LVS::JsonService::Logger.debug "Sent and received Request ID - #{request_id}"
+ LVS::JsonService::Logger.debug "Sent and received Request ID - #{sent_request_id}"
end
end
end
end
end