Permalink
Browse files

add mnemosyne sweeper to clear old filters

  • Loading branch information...
1 parent 70ff253 commit ca13dc73b271e29f549b51df8b58ccf4645cf3ae @igrigorik committed Mar 21, 2011
Showing with 59 additions and 14 deletions.
  1. +50 −6 lib/mneme.rb
  2. +9 −8 spec/mneme_spec.rb
View
@@ -5,7 +5,56 @@
require 'redis/connection/synchrony'
require 'bloomfilter-rb'
+module Mnemosyne
+ module Helper
+ def epoch(n, length)
+ (Time.now.to_i / length) - n
+ end
+
+ def epoch_name(namespace, n, length)
+ "mneme-#{namespace}-#{epoch(n, length)}"
+ end
+ end
+
+ class Sweeper
+ include Helper
+
+ def initialize(port, config, status, logger)
+ @status = status
+ @config = config
+ @logger = logger
+ end
+
+ def run
+ config = @config
+ logger = @logger
+
+ sweeper = Proc.new do
+ current = epoch_name(config['namespace'], 0, config['length'])
+ logger.info "Sweeping old filters, current epoch: #{current}"
+
+ conn = Redis.new
+ config['periods'].times do |n|
+ name = epoch_name(config['namespace'], n + config['periods'], config['length'])
+
+ conn.del(name)
+ logger.info "Removed: #{name}"
+ end
+ conn.client.disconnect
+ end
+
+ sweeper.call
+ EM.add_periodic_timer(config['length']) { sweeper.call }
+
+ @logger.info "Started Mnemosyne::Sweeper with #{@config['length']}s interval"
+ end
+ end
+end
+
class Mneme < Goliath::API
+ include Mnemosyne::Helper
+ plugin Mnemosyne::Sweeper
+
use ::Rack::Reloader, 0 if Goliath.dev?
use Goliath::Rack::Params
@@ -14,7 +63,6 @@ class Mneme < Goliath::API
use Goliath::Rack::Render
use Goliath::Rack::Heartbeat
use Goliath::Rack::ValidationError
-
use Goliath::Rack::Validation::RequestMethod, %w(GET POST)
def response(env)
@@ -67,12 +115,8 @@ def update_filters(keys)
private
- def epoch(n)
- (Time.now.to_i / config['length']) - n
- end
-
def filter(n)
- period = "mneme-#{config['namespace']}-#{epoch(n)}"
+ period = epoch_name(config['namespace'], n, config['length'])
filter = if env.key? period
env[period]
View
@@ -6,19 +6,20 @@
include Goliath::TestHelper
let(:err) { Proc.new { fail "API request failed" } }
+ let(:api_options) { { :config => File.expand_path(File.join(File.dirname(__FILE__), '..', 'config.rb')) } }
EventMachine::HttpRequest.use EventMachine::Middleware::JSONResponse
it 'responds to hearbeat' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
get_request({path: '/status'}, err) do |c|
c.response.should match('OK')
end
end
end
it 'should require an error if no key is provided' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
get_request({}, err) do |c|
c.response.should include 'error'
end
@@ -27,7 +28,7 @@
context 'single key' do
it 'should return 404 on missing key' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
get_request({:query => {:key => 'missing'}}, err) do |c|
c.response_header.status.should == 404
c.response['missing'].should include 'missing'
@@ -36,7 +37,7 @@
end
it 'should insert key into filter' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
post_request({:query => {key: 'abc'}}) do |c|
c.response_header.status.should == 201
@@ -52,7 +53,7 @@
context 'multiple keys' do
it 'should return 404 on missing keys' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
get_request({:query => {:key => ['a', 'b']}}, err) do |c|
c.response_header.status.should == 404
@@ -64,7 +65,7 @@
end
it 'should return 200 on found keys' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
post_request({:query => {key: ['abc1', 'abc2']}}) do |c|
c.response_header.status.should == 201
@@ -76,7 +77,7 @@
end
it 'should return 206 on mixed keys' do
- with_api(Mneme) do
+ with_api(Mneme, api_options) do
post_request({:query => {key: ['abc3']}}) do |c|
c.response_header.status.should == 201
@@ -89,4 +90,4 @@
end
-end
+end

0 comments on commit ca13dc7

Please sign in to comment.