Skip to content

Commit

Permalink
Merge pull request #8 from mfo/US/activejob
Browse files Browse the repository at this point in the history
Us/activejob
  • Loading branch information
flyerhzm committed Apr 14, 2015
2 parents 6534409 + 9fe6250 commit 4b8da52
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 50 deletions.
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.1.5
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
### Unreleased

# 0.4.0
* release for Rails>=4.2 with ActiveJob

# 0.3.0
* release for Rails<4.2
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ruby '2.1.5'

gem 'rspec'
gem 'mocha'
gem 'resque'
gem 'activejob'
65 changes: 65 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
GEM
specs:
activejob (4.2.0)
activesupport (= 4.2.0)
globalid (>= 0.3.0)
activesupport (4.2.0)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
diff-lcs (1.2.5)
globalid (0.3.3)
activesupport (>= 4.1.0)
i18n (0.7.0)
json (1.8.2)
metaclass (0.0.4)
minitest (5.5.1)
mocha (1.1.0)
metaclass (~> 0.0.1)
mono_logger (1.1.0)
multi_json (1.11.0)
rack (1.6.0)
rack-protection (1.5.3)
rack
redis (3.2.1)
redis-namespace (1.5.1)
redis (~> 3.0, >= 3.0.4)
resque (1.25.2)
mono_logger (~> 1.0)
multi_json (~> 1.0)
redis-namespace (~> 1.3)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
rspec (3.1.0)
rspec-core (~> 3.1.0)
rspec-expectations (~> 3.1.0)
rspec-mocks (~> 3.1.0)
rspec-core (3.1.7)
rspec-support (~> 3.1.0)
rspec-expectations (3.1.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.1.0)
rspec-mocks (3.1.3)
rspec-support (~> 3.1.0)
rspec-support (3.1.2)
sinatra (1.4.5)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
thread_safe (0.3.4)
tilt (1.4.1)
tzinfo (1.2.2)
thread_safe (~> 0.1)
vegas (0.1.11)
rack (>= 1.0.0)

PLATFORMS
ruby

DEPENDENCIES
activejob
mocha
resque
rspec
7 changes: 5 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ You can also add customized restriction as you like. For example, we have a job

class GenerateFacebookShares < Resque::Plugins::RestrictionJob
restrict :per_day => 40

def self.restriction_identifier(options)
[self.to_s, options["user_id"]].join(":")
end

#rest of your class here
end

options["user_id"] returns the user's facebook uid, the key point is that the different restriction_identifiers can restrict different job execution numbers.


Contributing
------------

Expand All @@ -70,6 +71,8 @@ Contributors
------------
Matt Conway :: matt@conwaysplace.com :: @mattconway

Martin Fourcade :: fourcade.m@gmail.com :: @mfourcade

Copyright
---------
Copyright (c) 2010 Richard Huang. See LICENSE for details.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.3.0
0.4.0
4 changes: 2 additions & 2 deletions lib/resque-restriction/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Resque
class Job
class <<self
alias_method :origin_reserve, :reserve

def reserve(queue)
if queue =~ /^#{Plugins::Restriction::RESTRICTION_QUEUE_PREFIX}/
# If processing the restriction queue, when poping and pushing to end,
Expand All @@ -14,7 +14,7 @@ def reserve(queue)
# and return
payload = Resque.pop(queue)
if payload
if ! constantize(payload['class']).repush(*payload['args'])
if !Object.const_get(payload['class']).repush(*payload['args'])
return new(queue, payload)
end
end
Expand Down
28 changes: 21 additions & 7 deletions lib/resque-restriction/restriction_job.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
require 'active_job'

module Resque
module Plugins

module Restriction
SECONDS = {
:per_minute => 60,
Expand Down Expand Up @@ -28,7 +31,6 @@ def before_perform_restriction(*args)
# if we get a 0 result back, the key wasn't set, so we know we are
# already tracking the count for that period'
period_active = ! Resque.redis.setnx(key, number.to_i - 1)

# If we are already tracking that period, then decrement by one to
# see if we are allowed to run, pushing to restriction queue to run
# later if not. Note that the value stored is the number of outstanding
Expand Down Expand Up @@ -76,10 +78,6 @@ def restriction_identifier(*args)
self.to_s
end

def restriction_queue_name
queue_name = Resque.queue_from_class(self)
"#{RESTRICTION_QUEUE_PREFIX}_#{queue_name}"
end

def seconds(period)
if SECONDS.keys.include? period
Expand Down Expand Up @@ -114,9 +112,25 @@ def mark_restriction_key_to_expire_for(key, period)
end
end

class RestrictionJob
class RestrictionJob < ActiveJob::Base
extend Restriction
end

before_perform do |job|
self.class.before_perform_restriction(*job.arguments)
end

after_perform do |job|
self.class.after_perform_restriction(*job.arguments)
end

rescue_from(StandardError) do |err|
self.class.on_failure_restriction(err, *self.arguments)
end

def self.restriction_queue_name
queue_name = self.new.queue_name
"#{Resque::Plugins::Restriction::RESTRICTION_QUEUE_PREFIX}_#{queue_name}"
end
end
end
end
2 changes: 1 addition & 1 deletion spec/redis-test.conf
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ databases 16
# Glue small output buffers together in order to send small replies in a
# single TCP packet. Uses a bit more CPU but most of the times it is a win
# in terms of number of queries per second. Use 'yes' if unsure.
glueoutputbuf yes
# glueoutputbuf yes

# Use object sharing. Can save a lot of memory if you have many common
# string in your dataset, but performs lookups against the shared objects
Expand Down
45 changes: 26 additions & 19 deletions spec/resque-restriction/restriction_job_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require File.expand_path('../spec_helper', File.dirname(__FILE__))

describe Resque::Plugins::RestrictionJob do
it "should follow the convention" do
xit "should follow the convention" do
Resque::Plugin.lint(Resque::Plugins::RestrictionJob)
end

Expand All @@ -19,7 +19,7 @@
Resque::Plugins::RestrictionJob.redis_key(:per_7200).should == "Resque::Plugins::RestrictionJob:#{Time.now.to_i / 7200}"
end
end

context "settings" do
it "get correct number to restriction jobs" do
OneDayRestrictionJob.settings.should == {:per_day => 100}
Expand All @@ -28,42 +28,51 @@
MultiCallRestrictionJob.settings.should == {:per_hour => 10, :per_300 => 2}
end
end


context 'restriction_queue_name' do
class MyJob < Resque::Plugins::RestrictionJob
queue_as 'awesome_queue_name'

def perform(args)
end
end

it 'concats restriction queue prefix with queue name' do
expect(MyJob.restriction_queue_name).to eq("#{Resque::Plugins::Restriction::RESTRICTION_QUEUE_PREFIX}_awesome_queue_name")
end
end

context "resque" do
include PerformJob

before(:each) do
Resque.redis.flushall
end

it "should set execution number and decrement it when one job first executed" do
result = perform_job(OneHourRestrictionJob, "any args")
result.should be_true
Resque.redis.get(OneHourRestrictionJob.redis_key(:per_hour)).should == "9"
end

it "should use restriction_identifier to set exclusive execution counts" do
result = perform_job(IdentifiedRestrictionJob, 1)
result.should be_true
result = perform_job(IdentifiedRestrictionJob, 1)
result.should be_true
result = perform_job(IdentifiedRestrictionJob, 2)
result.should be_true

Resque.redis.get(IdentifiedRestrictionJob.redis_key(:per_hour, 1)).should == "8"
Resque.redis.get(IdentifiedRestrictionJob.redis_key(:per_hour, 2)).should == "9"
end

it "should decrement execution number when one job executed" do
Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), 6)
result = perform_job(OneHourRestrictionJob, "any args")
result.should be_true

Resque.redis.get(OneHourRestrictionJob.redis_key(:per_hour)).should == "5"
end

it "should increment execution number when concurrent job completes" do
t = Thread.new do
result = perform_job(ConcurrentRestrictionJob, "any args")
result.should be_true
perform_job(ConcurrentRestrictionJob, "any args")
end
sleep 0.1
Resque.redis.get(ConcurrentRestrictionJob.redis_key(:concurrent)).should == "0"
Expand All @@ -72,24 +81,22 @@
end

it "should increment execution number when concurrent job fails" do
ConcurrentRestrictionJob.should_receive(:perform).and_raise("bad")
ConcurrentRestrictionJob.any_instance.should_receive(:perform).and_raise("bad")
perform_job(ConcurrentRestrictionJob, "any args") rescue nil
Resque.redis.get(ConcurrentRestrictionJob.redis_key(:concurrent)).should == "1"
end

it "should put the job into restriction queue when execution count < 0" do
Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), 0)
result = perform_job(OneHourRestrictionJob, "any args")
result.should_not be_true
# expect(result).to_not be(true)
Resque.redis.get(OneHourRestrictionJob.redis_key(:per_hour)).should == "0"
Resque.redis.lrange("queue:restriction_normal", 0, -1).should == [Resque.encode(:class => "OneHourRestrictionJob", :args => ["any args"])]
end

describe "expiration of period keys" do
class MyJob
extend Resque::Plugins::Restriction

def self.perform(*args)
class MyJob < Resque::Plugins::RestrictionJob
def perform(args)
end
end

Expand Down Expand Up @@ -201,13 +208,13 @@ def period
it "should push restricted jobs onto restriction queue" do
Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), -1)
Resque.should_receive(:push).once.with('restriction_normal', :class => 'OneHourRestrictionJob', :args => ['any args'])
OneHourRestrictionJob.repush('any args').should be_true
expect(OneHourRestrictionJob.repush('any args')).to be(true)
end

it "should not push unrestricted jobs onto restriction queue" do
Resque.redis.set(OneHourRestrictionJob.redis_key(:per_hour), 1)
Resque.should_not_receive(:push)
OneHourRestrictionJob.repush('any args').should be_false
expect(OneHourRestrictionJob.repush('any args')).to be(false)
end

end
Expand Down
1 change: 1 addition & 0 deletions spec/spec.opts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-b
--colour
--format
specdoc
Expand Down
Loading

0 comments on commit 4b8da52

Please sign in to comment.