Merge branch 'feature/options' into dev

This commit is contained in:
2011-03-10 00:27:26 +00:00
11 changed files with 147 additions and 97 deletions

View File

@@ -9,9 +9,10 @@ require 'time_ext'
require 'json'
require 'digest/sha1'
require 'redistat/collection'
require 'redistat/options'
require 'redistat/connection'
require 'redistat/database'
require 'redistat/collection'
require 'redistat/date'
require 'redistat/date_helper'
require 'redistat/event'

View File

@@ -4,6 +4,7 @@ module Redistat
base.extend(Database)
end
def db(ref = nil)
ref ||= @options[:connection_ref] if !@options.nil?
Redistat.connection(ref)
end
end

View File

@@ -1,40 +1,28 @@
module Redistat
class Event
include Database
include Options
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 = 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,
:connection_ref => nil,
:enable_grouping => true }
:enable_grouping => true,
:label_indexing => true }
end
def initialize(scope, label = nil, date = nil, stats = {}, opts = {}, meta = {}, is_new = true)
parse_options(opts)
@key = Key.new(scope, label, date, @options)
@stats = stats ||= {}
@meta = meta ||= {}
@new = is_new
end
def new?
@@ -75,7 +63,7 @@ module Redistat
def save
return false if !self.new?
Summary.update_all(@key, @stats, depth_limit, @connection_ref, @options[:enable_grouping])
Summary.update_all(@key, @stats, depth_limit, @options)
if @options[:store_event]
@id = self.next_id
db.hmset("#{self.scope}#{KEY_EVENT}#{@id}",

View File

@@ -1,20 +1,19 @@
module Redistat
class Key
include Redistat::Database
include Database
include Options
attr_accessor :options
def default_options
{ :depth => :hour }
end
def initialize(scope, label_name = nil, time_stamp = nil, options = {})
@options = default_options.merge(options || {})
def initialize(scope, label_name = nil, time_stamp = nil, opts = {})
parse_options(opts)
self.scope = scope
self.label = label_name if !label_name.nil?
self.date = time_stamp ||= Time.now
end
def default_options
{ :depth => :hour, :hashed_label => false }
end
def prefix
key = "#{@scope}"
key << "/#{label.name}" if !label.nil?
@@ -28,7 +27,7 @@ module Redistat
attr_reader :date
def depth
@options[:depth]
options[:depth]
end
def scope

View File

@@ -1,25 +1,24 @@
module Redistat
class Label
include Database
include Options
attr_reader :connection_ref
def self.create(name, options = {})
self.new(name, options).save
def default_options
{ :hashed_label => false }
end
def initialize(str, options = {})
@options = options
def self.create(name, opts = {})
self.new(name, opts).save
end
def initialize(str, opts = {})
parse_options(opts)
@raw = str.to_s
end
def to_s
@raw
end
def db
super(@options[:connection_ref])
end
def name
@options[:hashed_label] ? hash : self.to_s
@@ -35,6 +34,7 @@ module Redistat
end
def saved?
return true unless @options[:hashed_label]
@saved ||= false
end

View File

@@ -1,16 +1,18 @@
module Redistat
module Model
include Redistat::Database
include Database
include Options
def self.included(base)
base.extend(self)
end
#
# statistics store/fetch methods
#
def store(label, stats = {}, date = nil, meta = {}, opts = {})
def store(label, stats = {}, date = nil, opts = {}, meta = {})
Event.new(name, label, date, stats, options.merge(opts), meta).save
end
alias :event :store
@@ -27,47 +29,24 @@ module Redistat
:till => till }.merge(options.merge(opts)) )
end
#
# options methods
#
option_accessor :depth
option_accessor :class_name
option_accessor :store_event
option_accessor :hashed_label
option_accessor :label_indexing
alias :scope :class_name
def connect_to(opts = {})
Connection.create(opts.merge(:ref => name))
options[:connection_ref] = name
end
def hashed_label(boolean = nil)
if !boolean.nil?
options[:hashed_label] = boolean
else
options[:hashed_label] || nil
end
end
def class_name(class_name = nil)
if !class_name.nil?
options[:class_name] = class_name
else
options[:class_name] || nil
end
end
alias :scope :class_name
def depth(depth = nil)
if !depth.nil?
options[:depth] = depth
else
options[:depth] || nil
end
end
def store_event(boolean = nil)
if !boolean.nil?
options[:store_event] = boolean
else
options[:store_event] || nil
end
end
#
# resource access methods
@@ -78,10 +57,6 @@ module Redistat
end
alias :redis :connection
def options
@options ||= {}
end
def name
options[:class_name] || (@name ||= self.to_s)
end

43
lib/redistat/options.rb Normal file
View File

@@ -0,0 +1,43 @@
module Redistat
module Options
def self.included(base)
base.extend(ClassMethods)
end
class InvalidDefaultOptions < ArgumentError; end
module ClassMethods
def option_accessor(*opts)
opts.each do |option|
define_method(option) do |*args|
if !args.first.nil?
options[option.to_sym] = args.first
else
options[option.to_sym] || nil
end
end
end
end
end
def parse_options(opts)
opts ||= {}
@raw_options = opts
@options = default_options.merge(opts.reject { |k,v| v.nil? })
end
def default_options
{}
end
def options
@options ||= {}
end
def raw_options
@raw_options ||= {}
end
end
end

View File

@@ -2,21 +2,28 @@ module Redistat
class Summary
include Database
def self.update_all(key, stats = {}, depth_limit = nil, connection_ref = nil, enable_grouping = nil)
def self.default_options
{ :enable_grouping => true,
:label_indexing => true,
:connection_ref => nil }
end
def self.update_all(key, stats = {}, depth_limit = nil, opts = {})
stats ||= {}
return nil if stats.size == 0
depth_limit ||= key.depth
enable_grouping = true if enable_grouping.nil?
options = default_options.merge((opts || {}).reject { |k,v| v.nil? })
if enable_grouping
depth_limit ||= key.depth
if options[:enable_grouping]
stats = inject_group_summaries(stats)
key.groups.each { |k|
update_key(k, stats, depth_limit, connection_ref)
k.update_index # TODO: add a label_indexing option
update_key(k, stats, depth_limit, options[:connection_ref])
k.update_index if options[:label_indexing]
}
else
update_key(key, stats, depth_limit, connection_ref)
update_key(key, stats, depth_limit, options[:connection_ref])
end
end

View File

@@ -122,31 +122,31 @@ describe Redistat::Model do
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}, @time.hours_ago(4))
ModelHelper3.store("sheep.black", {:count => 2, :weight => 156}, @time)
ModelHelper3.store("sheep.black", {:count => 6, :weight => 461}, @time.hours_ago(4), :label_indexing => false)
ModelHelper3.store("sheep.black", {:count => 2, :weight => 156}, @time, :label_indexing => false)
db.keys("*").should be_empty # FIXME: index_labels option needs to be added, and enabled here
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", @time.hours_ago(2), @time.hours_since(1))
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(2), @time.hours_since(1), :label_indexing => false)
stats.total["count"].should == 2
stats.total["weight"].should == 156
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1))
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
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", @time.hours_ago(5), @time.hours_since(1))
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
stats.total.should == {}
ModelHelper3.connect_to(:port => 8379, :db => 14)
ModelHelper3.redis.client.db.should == 14
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1))
stats = ModelHelper3.fetch("sheep.black", @time.hours_ago(5), @time.hours_since(1), :label_indexing => false)
stats.total[:count].should == 8
stats.total[:weight].should == 617
end

36
spec/options_spec.rb Normal file
View File

@@ -0,0 +1,36 @@
require "spec_helper"
describe Redistat::Options do
before(:each) do
@helper = OptionsHelper.new
@helper.parse_options(:wtf => 'dude', :foo => 'booze')
end
it "should #parse_options" do
@helper.options[:hello].should == 'world'
@helper.options[:foo].should == 'booze'
@helper.options[:wtf].should == 'dude'
@helper.raw_options.should_not have_key(:hello)
end
it "should create option_accessors" do
@helper.hello.should == 'world'
@helper.hello('woooo')
@helper.hello.should == 'woooo'
end
end
class OptionsHelper
include Redistat::Options
option_accessor :hello
def default_options
{ :hello => 'world',
:foo => 'bar' }
end
end

View File

@@ -69,7 +69,7 @@ describe Redistat::Summary do
it "should not store key group summaries when option is disabled" do
stats = {"views" => 3, "visitors/eu" => 2, "visitors/us" => 4}
Redistat::Summary.update_all(@key, stats, :hour, nil, false)
Redistat::Summary.update_all(@key, stats, :hour, {:enable_grouping => false})
summary = db.hgetall(@key.to_s(:hour))
summary.should have(3).items
summary["views"].should == "3"