Added support for connection_ref's down throughout

the code, so models can connect to specific Redis
servers.

I believe a lot of the code needs some
restructuring at some point down the line to
handle multiple connections in a cleaner way, but
for now it'll do.
This commit is contained in:
2010-11-28 11:47:26 +00:00
parent dc162e0c89
commit 18e6125c6a
9 changed files with 111 additions and 37 deletions

View File

@@ -3,8 +3,8 @@ module Redistat
def self.included(base)
base.extend(Database)
end
def db
Redistat.connection
def db(ref = nil)
Redistat.connection(ref)
end
end
end

View File

@@ -4,21 +4,34 @@ module Redistat
attr_reader :id
attr_reader :key
attr_reader :connection_ref
attr_accessor :stats
attr_accessor :meta
attr_accessor :options
def initialize(scope, label = nil, date = nil, stats = {}, options = {}, meta = {}, is_new = true)
@options = default_options.merge(options)
@options = parse_options(options)
@connection_ref = @options[:connection_ref]
@key = Key.new(scope, label, date, @options)
@stats = stats ||= {}
@meta = meta ||= {}
@new = is_new
end
def db
super(@connection_ref)
end
def parse_options(options)
default_options.each do |opt, val|
options[opt] = val if options[opt].nil?
end
options
end
def default_options
{ :depth => :hour, :store_event => false }
{ :depth => :hour, :store_event => false, :connection_ref => nil }
end
def new?
@@ -59,7 +72,7 @@ module Redistat
def save
return false if !self.new?
Summary.update_all(@key, @stats, depth_limit)
Summary.update_all(@key, @stats, depth_limit, @connection_ref)
if @options[:store_event]
@id = self.next_id
db.hmset("#{self.scope}#{KEY_EVENT}#{@id}",

View File

@@ -8,6 +8,10 @@ module Redistat
@options = options
end
def db
super(@options[:connection_ref])
end
def valid_options?
return true if !@options[:scope].blank? && !@options[:label].blank? && !@options[:from].blank? && !@options[:till].blank?
false

View File

@@ -3,11 +3,16 @@ module Redistat
include Database
attr_reader :raw
attr_reader :connection_ref
def initialize(str, options = {})
@options = options
@raw = str.to_s
end
def db
super(@options[:connection_ref])
end
def name
@options[:hashed_label] ? hash : @raw

View File

@@ -1,5 +1,6 @@
module Redistat
module Model
include Redistat::Database
def self.included(base)
base.extend(self)
@@ -10,6 +11,16 @@ module Redistat
end
alias :event :store
def connect_to(opts = {})
Connection.create(opts.merge(:ref => name))
options[:connection_ref] = name
end
def connection
db(options[:connection_ref])
end
alias :redis :connection
def fetch(label, from, till, opts = {})
Finder.find({
:scope => name,

View File

@@ -2,21 +2,21 @@ module Redistat
class Summary
include Database
def self.update_all(key, stats = {}, depth_limit = nil)
def self.update_all(key, stats = {}, depth_limit = nil, connection_ref = nil)
stats ||= {}
depth_limit ||= key.depth
return nil if stats.size == 0
Date::DEPTHS.each do |depth|
update(key, stats, depth)
update(key, stats, depth, connection_ref)
break if depth == depth_limit
end
end
private
def self.update(key, stats, depth)
def self.update(key, stats, depth, connection_ref = nil)
stats.each do |field, value|
db.hincrby key.to_s(depth), field, value
db(connection_ref).hincrby key.to_s(depth), field, value
end
end

View File

@@ -1,6 +1,6 @@
require "redistat"
class ModelHelper
class ModelHelper1
include Redistat::Model
@@ -13,4 +13,11 @@ class ModelHelper2
store_event true
hashed_label true
end
class ModelHelper3
include Redistat::Model
connect_to :port => 8379, :db => 14
end

View File

@@ -5,11 +5,13 @@ describe Redistat::Model do
include Redistat::Database
before(:each) do
db.flushdb
ModelHelper1.redis.flushdb
ModelHelper2.redis.flushdb
ModelHelper3.redis.flushdb
end
it "should should name itself correctly" do
ModelHelper.send(:name).should == "ModelHelper"
ModelHelper1.send(:name).should == "ModelHelper1"
ModelHelper2.send(:name).should == "ModelHelper2"
end
@@ -18,49 +20,81 @@ describe Redistat::Model do
ModelHelper2.store_event.should == true
ModelHelper2.hashed_label.should == true
ModelHelper.depth.should == nil
ModelHelper.store_event.should == nil
ModelHelper.hashed_label.should == nil
ModelHelper.depth(:hour)
ModelHelper.depth.should == :hour
ModelHelper.store_event(true)
ModelHelper.store_event.should == true
ModelHelper.hashed_label(true)
ModelHelper.hashed_label.should == true
ModelHelper.options[:depth] = nil
ModelHelper.options[:store_event] = nil
ModelHelper.options[:hashed_label] = nil
ModelHelper.depth.should == nil
ModelHelper.store_event.should == nil
ModelHelper.hashed_label.should == nil
ModelHelper1.depth.should == nil
ModelHelper1.store_event.should == nil
ModelHelper1.hashed_label.should == nil
ModelHelper1.depth(:hour)
ModelHelper1.depth.should == :hour
ModelHelper1.store_event(true)
ModelHelper1.store_event.should == true
ModelHelper1.hashed_label(true)
ModelHelper1.hashed_label.should == true
ModelHelper1.options[:depth] = nil
ModelHelper1.options[:store_event] = nil
ModelHelper1.options[:hashed_label] = nil
ModelHelper1.depth.should == nil
ModelHelper1.store_event.should == nil
ModelHelper1.hashed_label.should == nil
end
it "should store and fetch stats" do
ModelHelper.store("sheep.black", {:count => 6, :weight => 461}, 4.hours.ago)
ModelHelper.store("sheep.black", {:count => 2, :weight => 156})
ModelHelper1.store("sheep.black", {:count => 6, :weight => 461}, 4.hours.ago)
ModelHelper1.store("sheep.black", {:count => 2, :weight => 156})
stats = ModelHelper.fetch("sheep.black", 2.hours.ago, 1.hour.from_now)
stats = ModelHelper1.fetch("sheep.black", 2.hours.ago, 1.hour.from_now)
stats.total["count"].should == 2
stats.total["weight"].should == 156
stats.first.should == stats.total
stats = ModelHelper.fetch("sheep.black", 5.hours.ago, 1.hour.from_now)
stats = ModelHelper1.fetch("sheep.black", 5.hours.ago, 1.hour.from_now)
stats.total[:count].should == 8
stats.total[:weight].should == 617
stats.first.should == stats.total
ModelHelper.store("sheep.white", {:count => 5, :weight => 393}, 4.hours.ago)
ModelHelper.store("sheep.white", {:count => 4, :weight => 316})
ModelHelper1.store("sheep.white", {:count => 5, :weight => 393}, 4.hours.ago)
ModelHelper1.store("sheep.white", {:count => 4, :weight => 316})
stats = ModelHelper.fetch("sheep.white", 2.hours.ago, 1.hour.from_now)
stats = ModelHelper1.fetch("sheep.white", 2.hours.ago, 1.hour.from_now)
stats.total[:count].should == 4
stats.total[:weight].should == 316
stats.first.should == stats.total
stats = ModelHelper.fetch("sheep.white", 5.hours.ago, 1.hour.from_now)
stats = ModelHelper1.fetch("sheep.white", 5.hours.ago, 1.hour.from_now)
stats.total[:count].should == 9
stats.total[:weight].should == 709
stats.first.should == stats.total
end
end
it "should connect to different Redis servers on a per-model basis" do
ModelHelper3.redis.client.db.should == 14
ModelHelper3.store("sheep.black", {:count => 6, :weight => 461}, 4.hours.ago)
ModelHelper3.store("sheep.black", {:count => 2, :weight => 156})
db.keys("*").should be_empty
ModelHelper1.redis.keys("*").should be_empty
db("ModelHelper3").keys("*").should have(5).items
ModelHelper3.redis.keys("*").should have(5).items
stats = ModelHelper3.fetch("sheep.black", 2.hours.ago, 1.hour.from_now)
stats.total["count"].should == 2
stats.total["weight"].should == 156
stats = ModelHelper3.fetch("sheep.black", 5.hours.ago, 1.hour.from_now)
stats.total[:count].should == 8
stats.total[:weight].should == 617
ModelHelper3.connect_to(:port => 8379, :db => 13)
ModelHelper3.redis.client.db.should == 13
stats = ModelHelper3.fetch("sheep.black", 5.hours.ago, 1.hour.from_now)
stats.total.should == {}
ModelHelper3.connect_to(:port => 8379, :db => 14)
ModelHelper3.redis.client.db.should == 14
stats = ModelHelper3.fetch("sheep.black", 5.hours.ago, 1.hour.from_now)
stats.total[:count].should == 8
stats.total[:weight].should == 617
end
end

View File

@@ -9,4 +9,4 @@ require 'rspec/autorun'
# use the test Redistat instance
Redistat.connect(:port => 8379, :db => 15)
Redistat.flush
Redistat.redis.flushdb