Commit 8e8c39f2 authored by sergio1990's avatar sergio1990

Merge branch 'connection-caching-ext'

parents 6263e870 f919a78e
......@@ -18,11 +18,13 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency "colorize", "0.7.2"
spec.add_dependency "colorize", ">= 0.7.2"
spec.add_dependency "active_redis", "0.0.9.1"
spec.add_dependency "activesupport", '>= 3.0.0'
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake", ">= 10.3.0"
spec.add_development_dependency "activesupport", ">= 3.1.0"
# spec.add_development_dependency "activesupport", ">= 3.1.0"
spec.add_development_dependency "rspec", "~> 3.0.0.beta"
spec.add_development_dependency "rspec-its", "1.0.1"
spec.add_development_dependency "pry-nav", "0.2.3"
......
......@@ -2,6 +2,7 @@ require "betfair_api_ng_rails/version"
require "betfair_api_ng_rails/errors"
require "betfair_api_ng_rails/api/request_methods"
require "betfair_api_ng_rails/railtie" if defined?(Rails)
require 'active_redis'
module BetfairApiNgRails
......@@ -19,6 +20,19 @@ module BetfairApiNgRails
autoload :Connection, 'betfair_api_ng_rails/api/connection'
autoload :Hashalator, 'betfair_api_ng_rails/api/hashalator'
module Caching
autoload :Helper, 'betfair_api_ng_rails/api/caching/helper'
autoload :ResponseCache, 'betfair_api_ng_rails/api/caching/response_cache'
module Models
autoload :BetfairCache, 'betfair_api_ng_rails/api/caching/models/betfair_cache'
end
end
module Logs
autoload :FileLogger, 'betfair_api_ng_rails/api/logs/file_logger'
......@@ -134,6 +148,7 @@ module BetfairApiNgRails
autoload :Parsing, 'betfair_api_ng_rails/api/connection_ext/parsing'
autoload :Formatting, 'betfair_api_ng_rails/api/connection_ext/formatting'
autoload :Logging, 'betfair_api_ng_rails/api/connection_ext/logging'
autoload :Caching, 'betfair_api_ng_rails/api/connection_ext/caching'
end
......
module BetfairApiNgRails
module Api
module Caching
module Helper
def createsig(body)
Digest::MD5.hexdigest sigflat(body)
end
def sigflat(body)
res = nil
if body.class == Hash
arr = []
body.each do |key, value|
arr << "#{sigflat key}=>#{sigflat value}"
end
res = arr
end
if body.class == Array
str = ''
res = body.map do |value|
sigflat value
end.sort!.each do |value|
str << value
end
end
if body.class != String
res = body.to_s << body.class.to_s
end
res || body
end
end
end
end
end
\ No newline at end of file
module BetfairApiNgRails
module Api
module Caching
module Models
class BetfairCache < ActiveRedis::Base
attributes method: :string,
params: :string,
response: :string
end
end
end
end
end
\ No newline at end of file
require 'ostruct'
require 'json'
module BetfairApiNgRails
module Api
module Caching
class ResponseCache
include Api::Caching::Helper
include Api::Caching::Models
attr_reader :method, :sig_params
def initialize(method, params)
@method = method
@sig_params = createsig(params)
end
def is_cached?
cache_result.count > 0
end
def responser
Api::Http::Responser.new prepare_response
end
def cache!(response)
BetfairCache.create(create_params(response)).expire expire_time
end
private
def cache_result
BetfairCache.where(method: method, params: sig_params)
end
def prepare_response
OpenStruct.new body: cache_result.first.response, code: '200'
end
def expire_time
BetfairApiNgRails.config.cache_expire
end
def create_params(response)
{ method: method, params: sig_params, response: JSON.dump(response) }
end
end
end
end
end
\ No newline at end of file
......@@ -14,7 +14,9 @@ module BetfairApiNgRails
:locale,
:formatter,
:keep_alive_session,
:keep_alive_url
:keep_alive_url,
:use_cache,
:cache_expire
def formatter=(value)
@formatter = BetfairApiNgRails::Api::FormatterFactory.initialize_formatter value
......
......@@ -8,6 +8,7 @@ module BetfairApiNgRails
provider.fetch method: method, params: hashing(params)
end
include Api::ConnectionExt::Caching
include Api::ConnectionExt::Logging
include Api::ConnectionExt::ErrorHandling
include Api::ConnectionExt::SsoidRefreshing
......
require 'active_support/inflector'
module BetfairApiNgRails
module Api
module ConnectionExt
module Caching
include BetfairApiNgRails::Api::Constants
def self.included(base)
base.send :class_eval, <<-CODE
def request_with_caching(method, params = {})
if is_caching_on?
BetfairApiNgRails.log.write("Cache is on! Trying to process with cache...")
process_with_caching method, params
else
BetfairApiNgRails.log.write("Cache is off!")
return request_without_caching(method, params)
end
end
alias_method :request_without_caching, :request
alias_method :request, :request_with_caching
CODE
end
private
def is_caching_on?
BetfairApiNgRails.config.use_cache
end
def process_with_caching(method, params)
cache_service = Api::Caching::ResponseCache.new(method, hashing(params))
if cache_service.is_cached?
BetfairApiNgRails.log.write(" Finded cached record!")
return cache_service.responser
else
BetfairApiNgRails.log.write(" Cached record not found!")
return make_real_request(method, params, cache_service)
end
end
def make_real_request(method, params, cache_service)
res = request_without_caching(method, params)
if need_caching?(res)
cache_service.cache!(res.result)
BetfairApiNgRails.log.write(" Result was cached!")
else
BetfairApiNgRails.log.write(" There are some problems 0_o... No any response cached...")
end
res
end
def need_caching?(res)
!(res.nil? || res.has_error?)
end
end
end
end
end
\ No newline at end of file
......@@ -9,4 +9,8 @@ BetfairApiNgRails.config do |config|
config.formatter = nil
config.keep_alive_session = true
# Caching settings
config.use_cache = false
config.cache_expire = 5 # in seconds
end
\ No newline at end of file
require 'spec_helper'
class TestObject
include BetfairApiNgRails::Api::Caching::Helper
end
describe BetfairApiNgRails::Api::Caching::Helper do
subject(:helper) { TestObject.new }
describe ".createsig" do
it "creates hex from sigflat result" do
expect(helper).to receive(:sigflat).with("some").and_return "some-sigflat"
expect(Digest::MD5).to receive(:hexdigest).with "some-sigflat"
helper.createsig "some"
end
describe 'real tests' do
context 'sigs equal values' do
let(:value1) { {key1: :value2} }
let(:value2) { {key1: :value2} }
it 'expects to be equal' do
val1 = helper.createsig(value1)
val2 = helper.createsig(value2)
expect(val1).to eq val2
end
end
context 'sigs different values' do
let(:value1) { {key1: :value2} }
let(:value2) { {key1: :value3} }
it 'expects not to be equal' do
val1 = helper.createsig(value1)
val2 = helper.createsig(value2)
expect(val1).not_to eq val2
end
end
end
end
describe ".sigflat" do
subject { helper.sigflat(value) }
context "when String passed" do
let(:value) { 'some' }
it { is_expected.to eq("some") }
end
context "when Integer passed" do
let(:value) { 1 }
it { is_expected.to eq("1Fixnum") }
end
context "when Hash passed" do
let(:value) { { key: :value } }
it { is_expected.to eq("{:key=>:value}Hash") }
end
context "when Array passed" do
let(:value) { ["val1", "val2"] }
it { is_expected.to eq("[\"val1\", \"val2\"]Array") }
end
end
end
\ No newline at end of file
require 'spec_helper'
describe BetfairApiNgRails::Api::Caching::ResponseCache do
let(:method) { :method }
let(:params) { :params }
subject(:cache) { described_class.new(method, params) }
before { allow_any_instance_of(described_class).to receive(:createsig).with(:params).and_return :sig_params }
describe "#is_cached?" do
before { expect(cache).to receive(:cache_result).and_return(cache_result) }
context 'when cache result returns item' do
let(:cache_result) { [double] }
its(:is_cached?) { is_expected.to be_truthy }
end
context 'when cache result returns no item' do
let(:cache_result) { [] }
its(:is_cached?) { is_expected.to be_falsey }
end
end
describe "#responser" do
before { expect(cache).to receive(:prepare_response).and_return :response }
it "returns http responser with cached info" do
expect(BetfairApiNgRails::Api::Http::Responser).to receive(:new).with(:response)
cache.responser
end
end
describe "#cache!" do
let(:response) { { some: :key } }
let(:record) { double(:record) }
before do
expect(cache).to receive(:create_params).with(response).and_return :create_params
expect(cache).to receive(:expire_time).and_return :expire_time
end
it "saves response in cache" do
expect(BetfairApiNgRails::Api::Caching::Models::BetfairCache).to receive(:create).with(:create_params).and_return record
expect(record).to receive(:expire).with :expire_time
cache.cache! response
end
end
context 'private method' do
describe "#cache_result" do
it "returns result from cache" do
expect(BetfairApiNgRails::Api::Caching::Models::BetfairCache).to receive(:where).with(method: :method, params: :sig_params)
cache.send :cache_result
end
end
describe "#prepare_response" do
let(:cache_result) { double(:cache_result, response: 'some response text') }
before { allow(cache).to receive(:cache_result).and_return [cache_result] }
subject(:response) { cache.send(:prepare_response) }
it { is_expected.to respond_to(:body) }
it { is_expected.to respond_to(:code) }
its(:body) { is_expected.to eq 'some response text' }
its(:code) { is_expected.to eq '200' }
end
describe "#expire_time" do
it "returns time from config" do
expect(BetfairApiNgRails).to receive_message_chain(:config, :cache_expire).and_return 4
expect(cache.send(:expire_time)).to eq 4
end
end
describe "#create_params" do
it "returns params for saving cache" do
expect(cache.send(:create_params, {some: :key})).to eq(method: :method, params: :sig_params, response: "{\"some\":\"key\"}")
end
end
end
end
\ No newline at end of file
$TESTING=true
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
module ActiveRedis
class Base
def self.attributes(*args); end
end
end
require 'rspec/its'
require 'betfair_api_ng_rails'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment