From 18e6125c6acb2f9e943d73cdbb2dedb414def64d Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sun, 28 Nov 2010 11:47:26 +0000 Subject: [PATCH] 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. --- lib/redistat/database.rb | 4 +- lib/redistat/event.rb | 19 +++++++-- lib/redistat/finder.rb | 4 ++ lib/redistat/label.rb | 5 +++ lib/redistat/model.rb | 11 +++++ lib/redistat/summary.rb | 8 ++-- spec/model_helper.rb | 9 ++++- spec/model_spec.rb | 86 ++++++++++++++++++++++++++++------------ spec/spec_helper.rb | 2 +- 9 files changed, 111 insertions(+), 37 deletions(-) diff --git a/lib/redistat/database.rb b/lib/redistat/database.rb index 7276270..4c9dae8 100644 --- a/lib/redistat/database.rb +++ b/lib/redistat/database.rb @@ -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 \ No newline at end of file diff --git a/lib/redistat/event.rb b/lib/redistat/event.rb index 7ba3967..54cb936 100644 --- a/lib/redistat/event.rb +++ b/lib/redistat/event.rb @@ -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}", diff --git a/lib/redistat/finder.rb b/lib/redistat/finder.rb index 77791ba..c0ee779 100644 --- a/lib/redistat/finder.rb +++ b/lib/redistat/finder.rb @@ -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 diff --git a/lib/redistat/label.rb b/lib/redistat/label.rb index 1236bd4..5ecf865 100644 --- a/lib/redistat/label.rb +++ b/lib/redistat/label.rb @@ -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 diff --git a/lib/redistat/model.rb b/lib/redistat/model.rb index 05e1f19..aea5308 100644 --- a/lib/redistat/model.rb +++ b/lib/redistat/model.rb @@ -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, diff --git a/lib/redistat/summary.rb b/lib/redistat/summary.rb index a538148..5dbcab1 100644 --- a/lib/redistat/summary.rb +++ b/lib/redistat/summary.rb @@ -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 diff --git a/spec/model_helper.rb b/spec/model_helper.rb index 87124c0..6b5489c 100644 --- a/spec/model_helper.rb +++ b/spec/model_helper.rb @@ -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 \ No newline at end of file diff --git a/spec/model_spec.rb b/spec/model_spec.rb index 3326257..8773bd1 100644 --- a/spec/model_spec.rb +++ b/spec/model_spec.rb @@ -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 \ No newline at end of file + 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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dfeccb4..bf5d986 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,4 +9,4 @@ require 'rspec/autorun' # use the test Redistat instance Redistat.connect(:port => 8379, :db => 15) -Redistat.flush +Redistat.redis.flushdb