Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

add Rack::Worker::expire(url, params)

  • Loading branch information...
commit 1e376b6727467641a3fbdff02462028c29e08501 1 parent 9cdf637
@csquared authored
View
8 Gemfile
@@ -3,10 +3,16 @@ source 'https://rubygems.org'
# Specify your gem's dependencies in rack-worker.gemspec
gemspec
+gem 'rake'
+gem 'pg'
+gem 'sequel'
+gem 'queue_classic'
+
group :test do
- gem 'rake'
gem 'rr'
gem 'webmock'
gem 'rack-test', :require => 'rack/test'
gem 'sinatra', :require => 'sinatra/base'
+ gem 'turn'
+ gem 'minitest'
end
View
15 lib/rack/worker.rb
@@ -22,7 +22,7 @@ def db
def self.cache
return @cache if defined? @cache
- @cache = PostgresCache.new(db_url, url_table_name, nil)
+ @cache = PostgresCache.new(db_url, cache_table_name, nil)
end
def self.queue
@@ -45,8 +45,8 @@ class << self
attr_writer :db_url
end
- def self.url_table_name
- ENV['RACK_WORKER_URL_TABLE'] || :rack_worker_cache
+ def self.cache_table_name
+ ENV['RACK_WORKER_CACHE_TABLE'] || :rack_worker_cache
end
# Given a string that starts with a slash,
@@ -55,7 +55,16 @@ def self.url_table_name
# Given a hash as the second argument,
# filter urls with those GET params
def self.expire(url, get_params = {})
+ raise "Expire only works with PosgresCache" unless cache.is_a? PostgresCache
+ self.find(url, get_params).update(:expires_on => Time.now)
+ end
+ def self.find(url, get_params)
+ data = cache.db[cache_table_name].filter(:key => /\A(response|env)-#{Regexp.escape(url)}\?/)
+ (get_params || []).each do |key, value|
+ data = data.filter("key like '%#{key}=#{value}%'")
+ end
+ data
end
def call(env)
View
16 lib/rack/worker/postgres_cache.rb
@@ -1,7 +1,11 @@
+require 'sequel'
+
module Rack
class Worker
class PostgresCache
- def initialize(db_url, table_name, expires_on)
+ attr :db
+
+ def initialize(db_url, table_name, expires_on = nil)
@db = ::Sequel.connect db_url
@table_name = table_name
@expires_on = expires_on
@@ -17,16 +21,22 @@ def initialize(db_url, table_name, expires_on)
def add(key, value, expires_on = nil)
expires_on ||= @expires_on
- @db[@table_name].insert(:key => key, :value => value)
+ @db[@table_name].insert(:key => key, :value => value, :expires_on => expires_on)
end
def get(key)
- (record = @db[@table_name].first(:key => key)) && (record[:value])
+ (record = _get(key)) && (record[:value])
end
def delete(key)
@db[@table_name].where(:key => key).delete
end
+
+ private
+ def _get(key)
+ @db[@table_name].filter("expires_on > now() or expires_on IS NULL").first(:key => key)
+ end
+
end
end
end
View
85 test/expire_test.rb
@@ -0,0 +1,85 @@
+require 'test_helper'
+
+class ExpireTest < Rack::Worker::TestCase
+
+ def app
+ ContainedSinatraApp
+ end
+
+ def teardown
+ Rack::Worker.db[Rack::Worker.cache_table_name].where("key like '%foo%'").delete
+ end
+
+ def visit(url)
+ get url
+ assert_equal 202, last_response.status
+ get url
+ assert_equal 200, last_response.status
+ end
+
+ def assert_expires_url(url)
+ visit url
+ yield
+ get url
+ assert_equal 202, last_response.status
+ end
+
+ def assert_doesnt_expire_url(url)
+ visit url
+ yield
+ get url
+ assert_equal 200, last_response.status
+ end
+
+ def test_expire_with_url
+ assert_expires_url '/foo' do
+ Rack::Worker.expire('/foo')
+ end
+ end
+
+ def test_expire_with_no_get_params_expires_all_with_url
+ assert_expires_url '/foo?query=param' do
+ Rack::Worker.expire('/foo')
+ end
+ end
+
+ def test_expires_with_one_get_param
+ assert_expires_url '/foo?query=param' do
+ Rack::Worker.expire('/foo', :query => 'param')
+ end
+ end
+
+ def test_expire_with_1_matching_param
+ assert_expires_url '/foo?query=param&query2=param2&query3=param3' do
+ Rack::Worker.expire('/foo', :query => 'param')
+ end
+ end
+
+ def test_expires_with_some_matching_params
+ assert_expires_url '/foo?query=param&query2=param2&query3=param3' do
+ Rack::Worker.expire('/foo', :query => 'param', :query2 => 'param2')
+ end
+ end
+
+ def test_expires_with_all_matching_params
+ assert_expires_url '/foo?query=param&query2=param2&query3=param3' do
+ Rack::Worker.expire('/foo', :query => 'param', :query2 => 'param2', :query3 => 'param3')
+ end
+ end
+
+ def requires_params_to_match
+ assert_doesnt_expire_url '/foo?query=param&query2=param2&query3=param3' do
+ Rack::Worker.expire('/foo', :query => 'param2')
+ end
+ end
+end
+
+class ExpireRaiseTest < Rack::Worker::TestCase
+ def test_raises_if_wrong_cache
+ @raise_test = true
+ Rack::Worker.cache = Object.new
+ assert_raises RuntimeError, 'Worker::expire only works with PostgresCache' do
+ Rack::Worker.expire('/foo')
+ end
+ end
+end
View
25 test/pg_cache_test.rb
@@ -0,0 +1,25 @@
+require 'test_helper'
+
+class PostgresCacheTest < Rack::Worker::TestCase
+
+ def setup
+ raise "Need to define TEST_DATABASE_URL" unless ENV['TEST_DATABASE_URL']
+ @cache = Rack::Worker::PostgresCache.new(ENV['TEST_DATABASE_URL'], :cache)
+ end
+
+ def teardown
+ @cache.db << "DROP TABLE cache;"
+ end
+
+ def test_adds_records
+ @cache.add('foo', 'bar')
+ assert_equal 'bar', @cache.get('foo')
+ end
+
+ def test_delete
+ @cache.add('foo', 'bar')
+ assert_equal 'bar', @cache.get('foo')
+ @cache.delete('foo')
+ assert_equal nil, @cache.get('foo')
+ end
+end
View
35 test/test_helper.rb
@@ -1,17 +1,50 @@
require 'bundler'
-Bundler.require :test
+Bundler.require :default, :test
require 'webmock/test_unit'
require "#{File.dirname(__FILE__)}/../lib/rack-worker"
+def QC.enqueue(function_call, *args)
+ eval("#{function_call} *args")
+end
+
class Rack::Worker::TestCase < Test::Unit::TestCase
include Rack::Test::Methods
include RR::Adapters::TestUnit
+ def setup
+ super
+ @old_cache = Rack::Worker.cache
+ end
+
def teardown
super
WebMock.reset!
+ Rack::Worker.cache = @old_cache if @old_cache
end
+
def default_test
#fu test::unit
end
end
+
+class ContainedSinatraApp < Sinatra::Base
+ use Rack::Worker
+
+ get '*' do
+ headers 'Content-Type' => 'text/test'
+ 'Hello, world'
+ end
+end
+
+class TestSinatraApp < Sinatra::Base
+ get '*' do
+ headers 'Content-Type' => 'text/test'
+ 'Hello, world'
+ end
+end
+
+class RackApp
+ def self.call(env)
+ [200, {"Content-Type" => "text/test"}, ['Hello, world']]
+ end
+end
View
28 test/worker_test.rb
@@ -22,16 +22,11 @@ def mock_queue.enqueue(function_call, *args)
class WorkerTest < Rack::Worker::TestCase
include QueueTest
- class TestClassApp
- def self.call(env)
- [200, {"Content-Type" => "text/test"}, ['Hello, world']]
- end
- end
def app
Rack::Builder.new do
use Rack::Worker
- run TestClassApp
+ run RackApp
end
end
@@ -71,23 +66,15 @@ def test_returns_response_in_queue
assert_equal 'application/json', last_response.headers['Content-Type']
assert_equal json, last_response.body
end
-
end
class SinatraTest < Rack::Worker::TestCase
include QueueTest
- class TestClassApp < Sinatra::Base
- get '*' do
- headers 'Content-Type' => 'text/test'
- 'Hello, world'
- end
- end
-
def app
Rack::Builder.new do
use Rack::Worker
- run TestClassApp
+ run TestSinatraApp
end
end
end
@@ -95,16 +82,7 @@ def app
class SinatraUseTest < Rack::Worker::TestCase
include QueueTest
- class TestClassApp < Sinatra::Base
- use Rack::Worker
-
- get '*' do
- headers 'Content-Type' => 'text/test'
- 'Hello, world'
- end
- end
-
def app
- TestClassApp
+ ContainedSinatraApp
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.