Skip to content

Commit

Permalink
Try to bring this to the modern age
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewrudy committed Jul 24, 2013
1 parent 1f6ab14 commit 930726c
Show file tree
Hide file tree
Showing 12 changed files with 192 additions and 121 deletions.
2 changes: 2 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
--color
--format progress
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# A sample Gemfile
source "https://rubygems.org"

gem "activesupport"
gem "activerecord"
gem "mysql2"
gem "rspec"
46 changes: 46 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
GEM
remote: https://rubygems.org/
specs:
activemodel (4.0.0)
activesupport (= 4.0.0)
builder (~> 3.1.0)
activerecord (4.0.0)
activemodel (= 4.0.0)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.0)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activesupport (4.0.0)
i18n (~> 0.6, >= 0.6.4)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
arel (4.0.0)
atomic (1.1.10)
builder (3.1.4)
diff-lcs (1.2.4)
i18n (0.6.4)
minitest (4.7.5)
multi_json (1.7.7)
mysql2 (0.3.13)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.4)
rspec-expectations (2.14.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.14.1)
thread_safe (0.1.2)
atomic
tzinfo (0.3.37)

PLATFORMS
ruby

DEPENDENCIES
activerecord
activesupport
mysql2
rspec
17 changes: 4 additions & 13 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
require 'rake'
require 'spec'
require 'spec/rake/spectask'
require 'rake/rdoctask'

desc 'Default: run the specs.'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
task :default => :spec

desc 'Run specs for rude_q plugin'
Spec::Rake::SpecTask.new(:spec) do |t|
t.spec_opts = ['--options', "\"spec/spec.opts\""]
t.spec_files = FileList['spec/**/*_spec.rb']
end

require 'rdoc/task'
desc 'Generate documentation for the rude_q plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
RDoc::Task.new do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'RudeQ'
rdoc.options << '--line-numbers' << '--inline-source'
Expand Down
29 changes: 15 additions & 14 deletions lib/rude_q.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module ClassMethods
def cleanup!(expiry=1.hour)
self.delete_all(["processed = ? AND updated_at < ?", true, expiry.to_i.ago])
end

# Add any serialize-able +data+ to the queue +queue_name+ (strings and symbols are treated the same)
# RudeQueue.set(:sausage_queue, Sausage.new(:sauce => "yummy"))
# RudeQueue.set("sausage_queue", Sausage.new(:other => true))
Expand Down Expand Up @@ -62,7 +62,7 @@ def set(queue_name, data)
# -> nil
def get(queue_name)
qname = sanitize_queue_name(queue_name)

fetch_with_lock(qname) do |record|
if record
processed!(record)
Expand Down Expand Up @@ -109,7 +109,7 @@ def backlog(queue_name=nil)
end
self.count(:conditions => conditions)
end

def fetch_with_lock(qname, &block) # :nodoc:
lock = case queue_options[:lock]
when :pessimistic then RudeQ::PessimisticLock
Expand All @@ -119,7 +119,7 @@ def fetch_with_lock(qname, &block) # :nodoc:
end
lock.fetch_with_lock(self, qname, &block)
end

# class method to make it more easily stubbed
def processed!(record) # :nodoc:
case queue_options[:processed]
Expand All @@ -132,7 +132,7 @@ def processed!(record) # :nodoc:
end
end
protected :processed!

# configure your RudeQ
# ==== :processed - what do we do after retrieving a queue item?
# * <tt>:set_flag</tt> - set the +processed+ flag to +true+ (keep data in the db) [*default*]
Expand All @@ -152,33 +152,33 @@ def data=(value) # :nodoc:
self[:data] = YAML.dump(value)
end
private

def sanitize_queue_name(queue_name) # :nodoc:
queue_name.to_s
end
end

# uses standard ActiveRecord :lock => true
# this will invoke a lock on the particular queue
# eg. daemon1: RudeQueue.get(:abc)
# daemon2: RudeQueue.get(:abc) - will have to wait for daemon1 to finish
# daemon3: RudeQueue.get(:def) - will avoid the lock
module PessimisticLock
class << self

def fetch_with_lock(klass, qname) # :nodoc:
klass.transaction do
record = klass.find(:first,
:conditions => {:queue_name => qname, :processed => false},
:lock => true, :order => "id ASC", :limit => 1)

return yield(record)
end
end

end
end

# a crazy hack around database locking
# that I thought was a good idea
# turns out we can't make it use transactions properly
Expand All @@ -189,14 +189,15 @@ def fetch_with_lock(klass, qname) # :nodoc:
# and as of RudeQueue2, you'll need to manually add the "token" column
module TokenLock
class << self

require 'digest/sha1'

require 'socket'

def fetch_with_lock(klass, qname) # :nodoc:
token = get_unique_token
klass.update_all(["token = ?", token], ["queue_name = ? AND processed = ? AND token IS NULL", qname, false], :limit => 1, :order => "id ASC")
record = klass.find_by_queue_name_and_token_and_processed(qname, token, false)

return yield(record)
end

Expand Down
10 changes: 6 additions & 4 deletions lib/rude_q/worker.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'rude_q/scope'

# example worker class: lib/my_worker.rb
# class MyWorker < RudeQ::Worker
# def queue_name
Expand Down Expand Up @@ -25,11 +27,11 @@ class Worker
def queue_name
raise NotImplementedError
end

def do_work(data)
raise NotImplementedError
end

def do!
logger.info("starting up")
if work = self.queue.get
Expand All @@ -39,8 +41,8 @@ def do!
logger.info("couldn't find any work")
end
logger.info("finished for now")
end
end

def logger
unless @logger
@logger = Logger.new(RAILS_ROOT + "/log/#{self.class.to_s.underscore}_#{RAILS_ENV}.log")
Expand Down
6 changes: 5 additions & 1 deletion spec/database.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# CREATE USER 'rude_q'@'localhost';
# GRANT ALL PRIVILEGES ON rude_q_test.* to 'rude_q'@'localhost';
# CREATE DATABASE rude_q_test

rude_q_test:
adapter: mysql
adapter: mysql2
username: rude_q
database: rude_q_test
9 changes: 6 additions & 3 deletions spec/models/rude_queue.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
require 'rude_q'

class RudeQueue < ActiveRecord::Base
include RudeQ

class << self
def processed_with_raise_hack!(*args)
processed_without_raise_hack!(*args)
raise RuntimeError if raise_on_processed # want to be able to raise afterwards to check transactions
end
alias_method_chain :processed!, :raise_hack
alias :processed_without_raise_hack! :processed!
alias :processed! :processed_with_raise_hack!
attr_accessor :raise_on_processed
end

end

Loading

0 comments on commit 930726c

Please sign in to comment.