Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'redis'

  • Loading branch information...
commit 6ba91a2f8107dc5abfb465741d215dd40fa619fc 2 parents 7da79d6 + ae7c876
@igrigorik authored
View
5 Gemfile
@@ -2,6 +2,11 @@ source "http://rubygems.org"
gem "uuid"
gem "yajl-ruby"
+gem "redis"
+
+platforms :mri_18 do
+ gem "SystemTimer"
+end
group :test do
gem "rack"
View
24 Gemfile.lock
@@ -0,0 +1,24 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ SystemTimer (1.2)
+ macaddr (1.0.0)
+ rack (1.2.1)
+ rake (0.8.7)
+ redis (2.0.5)
+ rspec (1.3.0)
+ uuid (2.3.1)
+ macaddr (~> 1.0)
+ yajl-ruby (0.7.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ SystemTimer
+ rack
+ rake
+ redis
+ rspec
+ uuid
+ yajl-ruby
View
17 examples/memory_runner.rb
@@ -0,0 +1,17 @@
+require 'rubygems'
+require 'rack'
+
+$LOAD_PATH.unshift 'lib'
+$LOAD_PATH.unshift 'examples'
+
+require 'rack/speedtracer'
+require 'someapp'
+
+builder = Rack::Builder.new do
+ use Rack::CommonLogger
+ use Rack::SpeedTracer
+
+ run SomeApp.new
+end
+
+Rack::Handler::Thin.run builder.to_app, :Port => 4567
View
17 examples/redis_runner.rb
@@ -0,0 +1,17 @@
+require 'rubygems'
+require 'rack'
+
+$LOAD_PATH.unshift 'lib'
+$LOAD_PATH.unshift 'examples'
+
+require 'rack/speedtracer'
+require 'someapp'
+
+builder = Rack::Builder.new do
+ use Rack::CommonLogger
+ use Rack::SpeedTracer, :storage => Rack::SpeedTracer::Storage::Redis
+
+ run SomeApp.new
+end
+
+Rack::Handler::Thin.run builder.to_app, :Port => 4567
View
17 examples/runner.rb → examples/someapp.rb
@@ -1,9 +1,3 @@
-require 'rubygems'
-require 'rack'
-
-$LOAD_PATH.unshift 'lib'
-require 'rack/speedtracer'
-
class SomeApp
def call(env)
env['st.tracer'].run('computation: 5**100000') do
@@ -22,13 +16,4 @@ def call(env)
[200, {"Content-Type" => "text/plain"}, "Hello World"]
end
-end
-
-builder = Rack::Builder.new do
- use Rack::CommonLogger
- use Rack::SpeedTracer
-
- run SomeApp.new
-end
-
-Rack::Handler::Thin.run builder.to_app, :Port => 4567
+end
View
2  lib/rack/speedtracer.rb
@@ -4,6 +4,8 @@
require 'rack/speedtracer/context'
require 'rack/speedtracer/tracer'
+require 'rack/speedtracer/memory_storage'
+require 'rack/speedtracer/redis_storage'
# auto-instrument Rails 3 applications
if defined? Rails
View
11 lib/rack/speedtracer/context.rb
@@ -9,12 +9,13 @@ class Context
attr_accessor :db
def initialize(app, options = {}, &blk)
+ options = {
+ :storage => Storage::Memory
+ }.merge(options)
+
@app = app
@uuid = UUID.new
- @db = {}
-
- # TODO: storage strategy...
- # initialize_options with options
+ @db = options.delete(:storage).new(options)
yield self if block_given?
end
@@ -74,4 +75,4 @@ def call(env)
end
end
-end
+end
View
17 lib/rack/speedtracer/memory_storage.rb
@@ -0,0 +1,17 @@
+require 'forwardable'
+
+module Rack
+ module SpeedTracer
+ module Storage
+ class Memory
+ extend Forwardable
+
+ def_delegators :@db_hash, :[], :[]=
+
+ def initialize(options)
+ @db_hash = {}
+ end
+ end
+ end
+ end
+end
View
39 lib/rack/speedtracer/redis_storage.rb
@@ -0,0 +1,39 @@
+require 'redis'
+
+module Rack
+ module SpeedTracer
+ module Storage
+
+ class Redis
+ def initialize(options)
+ @redis = ::Redis.new(options[:redis_options] || {})
+ @ttl = options[:trace_ttl] || 600
+ @namespace = options[:namespace] || "speedtracer"
+ end
+
+ def [](trace_id)
+ @redis.get(namespace_key(trace_id))
+
+ rescue Exception => e
+ puts "#{self.class} : #{e}"
+ end
+
+ def []=(trace_id, trace)
+
+ key = namespace_key(trace_id)
+ @redis.set(key, trace)
+ @redis.expire(key, @ttl)
+
+ rescue Exception => e
+ puts "#{self.class} : #{e}"
+ end
+
+ private
+
+ def namespace_key(key)
+ "#{@namespace}:#{key}"
+ end
+ end
+ end
+ end
+end
View
22 spec/speedtracer_spec.rb → spec/rack/speedtracer/context_spec.rb
@@ -19,6 +19,26 @@
end
middleware.db.should == db
end
+
+ context 'storage engine' do
+ it 'takes an optional storage class' do
+ class SomeStorageClass
+ def initialize(options);end
+ end
+ st = Rack::SpeedTracer.new(app, :storage => SomeStorageClass)
+ st.db.class.should == SomeStorageClass
+ end
+
+ it 'should default to memory storage' do
+ st = Rack::SpeedTracer.new(app)
+ st.db.class.should == Rack::SpeedTracer::Storage::Memory
+ end
+
+ it 'should accept redis storage' do
+ st = Rack::SpeedTracer.new(app, :storage => Rack::SpeedTracer::Storage::Redis)
+ st.db.class.should == Rack::SpeedTracer::Storage::Redis
+ end
+ end
end
describe 'response' do
@@ -54,4 +74,4 @@
response.status.should == 404
end
end
-end
+end
View
29 spec/rack/speedtracer/redis_storage_spec.rb
@@ -0,0 +1,29 @@
+require 'spec_helper'
+require 'rack/speedtracer/redis_storage'
+
+describe Rack::SpeedTracer::Storage::Redis do
+ before(:each) do
+ @mock_redis = mock('redis')
+ Redis.stub(:new).and_return(@mock_redis)
+ @storage_klass = Rack::SpeedTracer::Storage::Redis
+ end
+
+ it "fetches traces from Redis" do
+ r = @storage_klass.new({})
+ @mock_redis.should_receive(:get).with("speedtracer:some_trace")
+ trace = r['some_trace']
+ end
+
+ it "saves traces in Redis with a default expiry time" do
+ r = @storage_klass.new({})
+ @mock_redis.should_receive(:set).with("speedtracer:some_trace", "trace_contents")
+ @mock_redis.should_receive(:expire).with("speedtracer:some_trace", 600)
+ r['some_trace'] = "trace_contents"
+ end
+
+ it "allows the key namespace to be changed" do
+ r = @storage_klass.new(:namespace => "my_namespace")
+ @mock_redis.should_receive(:get).with("my_namespace:my_trace")
+ trace = r['my_trace']
+ end
+end
View
0  spec/tracer_spec.rb → spec/rack/speedtracer/tracer_spec.rb
File renamed without changes
Please sign in to comment.
Something went wrong with that request. Please try again.