Skip to content

Commit

Permalink
Added API
Browse files Browse the repository at this point in the history
  • Loading branch information
jurriaan committed Jan 5, 2012
1 parent 2a4fe0c commit 637827f
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 22 deletions.
1 change: 1 addition & 0 deletions lib/fnordmetric.rb
Expand Up @@ -123,6 +123,7 @@ def self.standalone

end

require "fnordmetric/api"
require "fnordmetric/inbound_stream"
require "fnordmetric/worker"
require "fnordmetric/widget"
Expand Down
37 changes: 37 additions & 0 deletions lib/fnordmetric/api.rb
@@ -0,0 +1,37 @@
require 'securerandom'
class FnordMetric::API
@@opts = nil
def initialize opts
@@opts = FnordMetric.default_options opts
connect
end

def connect
@redis = @@opts[:redis] if @@opts[:redis]
@redis = Redis.connect(:url => @@opts[:redis_url])
end

def event event_data
push_event get_next_uuid, event_data
end

def disconnect
@redis.quit
end

private

def push_event(event_id, event_data)
prefix = @@opts[:redis_prefix]
@redis.hincrby "#{prefix}-testdata", "events_received", 1
@redis.hincrby "#{prefix}-stats", "events_received", 1
@redis.set "#{prefix}-event-#{event_id}", event_data
@redis.lpush "#{prefix}-queue", event_id
@redis.expire "#{prefix}-event-#{event_id}", @@opts[:event_queue_ttl]
event_id
end

def get_next_uuid
SecureRandom.uuid
end
end
27 changes: 5 additions & 22 deletions lib/fnordmetric/inbound_stream.rb
@@ -1,6 +1,4 @@
require 'securerandom'
class FnordMetric::InboundStream < EventMachine::Connection

@@opts = nil

def self.start(opts)
Expand All @@ -13,18 +11,6 @@ def receive_data(chunk)
EM.defer{ next_event }
end

def push_event(event_id, event_data)
prefix = @@opts[:redis_prefix]

@redis.hincrby "#{prefix}-stats", "events_received", 1
@redis.set "#{prefix}-event-#{event_id}", event_data
@redis.lpush "#{prefix}-queue", event_id
@redis.expire "#{prefix}-event-#{event_id}", @@opts[:event_queue_ttl]

@events_buffered -= 1
close_connection?
end

def next_event
read_next_event
push_next_event
Expand All @@ -39,20 +25,18 @@ def read_next_event

def push_next_event
return true if @events.empty?
push_event(get_next_uuid, @events.pop)
@api.event event_data
@events_buffered -= 1
close_connection?
EM.next_tick(&method(:push_next_event))
end

def get_next_uuid
SecureRandom.uuid
end

def close_connection?
@redis.quit unless @streaming || (@events_buffered!=0)
@api.disconnect unless @streaming || (@events_buffered!=0)
end

def post_init
@redis = Redis.connect(:url => @@opts[:redis_url])
@api = API.new(@@opts)
@events_buffered = 0
@streaming = true
@buffer = ""
Expand All @@ -63,5 +47,4 @@ def unbind
@streaming = false
close_connection?
end

end
107 changes: 107 additions & 0 deletions spec/api_spec.rb
@@ -0,0 +1,107 @@
require ::File.expand_path('../spec_helper.rb', __FILE__)

describe FnordMetric::Event do

include FnordMetric

before(:all) do
@now = Time.utc(1992,01,13,5,23,23).to_i
@redis = Redis.new
@redis_wrap = RedisWrap.new(@redis)

@namespace = "fnordmetric-test-ns1234-api"
@timeline = "#{@namespace}-timeline"

@opts = {
:namespace_prefix => "#{@namespace}",
:redis_prefix => "fnordmetric-test",
:redis => @redis
}
@api = API.new @opts
end

describe "finding events using API" do

before(:each) do
@redis.keys("fnordmetric-test-*").each { |k| @redis.del(k) }
end

it "should find all events" do
create_event({:_type => "foo", :_time => @now})
create_event({:_type => "foo", :_time => @now})
Event.all(@opts).length.should == 2
end

it "should find all events and return event objects" do
create_event({:_type => "foo", :_time => @now})
Event.all(@opts).first.should be_a(FnordMetric::Event)
end

it "should find all events and returnevent objects with time" do
create_event({:_type => "Fn0rd", :blah => :blubb, :_time => @now})
events = Event.all(@opts)
events.first.time.to_i.should == @now
end

it "should find an event and return a event object" do
event_id = create_event({:_type => "Fn0rd", :_time => @now})
event = Event.find(event_id, @opts)
event.should be_a(FnordMetric::Event)
event.type.should == "Fn0rd"
end

it "should find an event and return a event object with data" do
event_id = create_event({:_type => "Fn0rd", :blah => :blubb, :_time => @now})
event = Event.find(event_id, @opts)
event.data(:blah).should == "blubb"
end

it "should find an event and return a event object with id" do
event_id = create_event({:_type => "Fn0rd", :blah => :blubb, :_time => @now})
event = Event.find(event_id, @opts)
event.id.should == event_id
end

it "should find all in the correct order" do
create_event({:_type => "foo", :_time => @now-17})
create_event({:_type => "foo", :_time => @now-23})
create_event({:_type => "foo", :_time => @now-42})
create_event({:_type => "foo", :_time => @now-5})
Event.all(@opts).length.should == 4
end

it "should find all events since a given time, including that exact time" do
create_event({:_type => "foo", :_time => @now-42})
create_event({:_type => "foo", :_time => @now-23})
create_event({:_type => "foo", :_time => @now-17})
create_event({:_type => "foo", :_time => @now-5})
Event.all(@opts).length.should == 4
Event.all(@opts.merge(:since => @now-42)).length.should == 4
Event.all(@opts.merge(:since => @now-23)).length.should == 3
Event.all(@opts.merge(:since => @now-22)).length.should == 2
Event.all(@opts.merge(:since => @now-17)).length.should == 2
Event.all(@opts.merge(:since => @now-16)).length.should == 1
Event.all(@opts.merge(:since => @now-5)).length.should == 1
end

it "should find a maximum number of events" do
create_event( {:_type => "foo", :_time => @now-42})
create_event( {:_type => "foo", :_time => @now-23})
create_event( {:_type => "foo", :_time => @now-17})
create_event( {:_type => "foo", :_time => @now-5})
Event.all(@opts).length.should == 4
Event.all(@opts.merge(:limit => 2)).length.should == 2
end



def create_event(event_data)
event_id = @api.event event_data.to_json
@redis_wrap.zadd(@timeline, event_data.delete(:_time), event_id)
event_id
end

end


end

0 comments on commit 637827f

Please sign in to comment.