afterparty 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: 1cd702bf393ba9846ebeea3e8195dd7f76914488
4
- data.tar.gz: a7f24532f757b22660d31720ccd0bec948ba7545
5
- !binary "U0hBNTEy":
6
- metadata.gz: 86e634284043827e87dcdc3fce39e5be359a3592077dca1427041faa9f1fd147e9d1ed374b6241643836617b5393da9822fca6d985db39d5c6431fa53d5667b1
7
- data.tar.gz: c49dbbed658e44ab6a7eb1cc55d0528621a6eb17612744e7f733a00cf91770d0c398d360f1628b7c20cf44310f1657f515c41b773d6f61263479470698493ec2
2
+ SHA1:
3
+ metadata.gz: f2a6ac0e585c1d786ce00d1cd91863f5bead9af4
4
+ data.tar.gz: c276f1d73253a5ab5189689ce72cc39e8e1db8fa
5
+ SHA512:
6
+ metadata.gz: 24e8c2dbe66ebee04fab02fdfff9e9430588b1df9d23b71ec1e76e6c6b9002ae80afb5679f3f5ad91252c1a3710758a070b9afaa669866fcc964529c828f4a0a
7
+ data.tar.gz: 1c7cff779dd6172e921ccfd8f7015bc84e6a720709356e3bbc363089112f3116f659c7b670cc43f858b70b719d16d3675872b37c57103c1743c2957b0f40690d
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.sqlite3
data/Gemfile CHANGED
@@ -9,4 +9,7 @@ gem 'guard-rspec'
9
9
  gem 'ruby_gntp'
10
10
  gem 'redis'
11
11
  gem 'sqlite3'
12
- gem 'genspec'
12
+ gem 'genspec'
13
+ gem 'fileutils'
14
+ gem 'simplecov'
15
+ gem 'coveralls', require: false
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Afterparty
2
2
 
3
3
  [![Build Status](https://travis-ci.org/hstove/afterparty.png?branch=master)](https://travis-ci.org/hstove/afterparty)
4
+ [![Code Climate](https://codeclimate.com/github/hstove/afterparty.png)](https://codeclimate.com/github/hstove/afterparty)
5
+ [![Coverage Status](https://coveralls.io/repos/hstove/afterparty/badge.png)](https://coveralls.io/r/hstove/afterparty)
4
6
 
5
7
  A Rails 3 & 4 compatible queue with support for executing jobs in the future and persistence with ActiveRecord.
6
8
 
@@ -2,8 +2,4 @@ Afterparty::Engine.routes.draw do
2
2
  get "/" => "afterparty/dashboard#index", as: :dashboard
3
3
  get "/run" => "afterparty/dashboard#run", as: :run_job
4
4
  get "/delete" => "afterparty/dashboard#destroy", as: :destroy_job
5
- end
6
-
7
- Rails.application.routes.draw do
8
- mount Afterparty::Engine, at: "afterparty", as: "afterparty_engine"
9
5
  end
@@ -5,21 +5,6 @@ Dir[File.expand_path('../afterparty/*', __FILE__)].each { |f| require f }
5
5
 
6
6
 
7
7
  module Afterparty
8
- def self.clear namespace=:default
9
- redis_call namespace, :del
10
- end
11
-
12
- def self.redis_call namespace, command, *args
13
- @@redis.send(command, redis_queue_name(namespace), *args)
14
- end
15
-
16
- def self.redis_queue_name namespace=:default
17
- "afterparty_#{namespace}_queue"
18
- end
19
-
20
- def self.queues
21
- # @@redis.smembers "afterparty_queues"
22
- end
23
8
 
24
9
  # return timestamp of :execute_at or current time
25
10
  def self.queue_time job
@@ -30,30 +15,21 @@ module Afterparty
30
15
  def self.job_valid? job
31
16
  job.respond_to?(:execute_at) && !job.execute_at.nil?
32
17
  end
33
-
18
+
34
19
  def self.load(raw)
35
20
  begin
36
- # postgres converts it to utf-8
37
- # raw.encode!("ascii")
38
21
  begin
39
- # job = Marshal.load(raw)
40
- # job = Marshal.load(job) if String === job
41
22
  return YAML.load(raw)
42
23
  rescue ArgumentError => e
43
24
  # lots of yaml load errors are because something that hasn't been
44
25
  # required. recursively require on these errors
45
26
  # Invoke the autoloader and try again if object's class is undefined
46
27
  if e.message =~ /undefined class\/module (.*)$/
47
- # puts "autoloading #{$1}"
48
28
  $1.constantize rescue return nil
49
29
  end
50
30
  return load(raw)
51
31
  end
52
32
  rescue Exception => e
53
- puts e
54
- puts "Exception while unmarshaling a job:"
55
- puts e.message
56
- puts e.backtrace
57
33
  return nil
58
34
  end
59
35
  end
@@ -5,7 +5,7 @@ class AfterpartyJob < ::ActiveRecord::Base
5
5
 
6
6
  validates_presence_of :job_dump, :execute_at, :queue
7
7
 
8
- scope :namespaced, lambda { |name| where(queue: name) }
8
+ scope :namespaced, lambda { |name| where(queue: name) if name }
9
9
  scope :incomplete, -> { where(completed: false).order("execute_at") }
10
10
  scope :valid, -> { incomplete.where(execute_at: 10.years.ago..DateTime.now) }
11
11
  scope :completed, -> { where(completed: true).order("execute_at desc") }
@@ -13,7 +13,6 @@ module Afterparty
13
13
  @job_id = job.afterparty_job_id if @job.respond_to? :afterparty_job_id
14
14
  @queue_name = job.afterparty_queue if @job.respond_to? :afterparty_queue
15
15
  rescue Exception => e
16
- ap "Error during load: #{e.message}"
17
16
  @job = nil
18
17
  end
19
18
  @raw = _raw
@@ -27,10 +26,5 @@ module Afterparty
27
26
  nil
28
27
  end
29
28
  end
30
-
31
- def raw_string
32
- ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
33
- ic.iconv(@raw.dup + ' ')[0..-2]
34
- end
35
29
  end
36
30
  end
@@ -1,41 +1,37 @@
1
1
  module Afterparty
2
- class MailerJob
3
- attr_accessor :execute_at, :mail, :clazz, :method, :args
4
- def initialize clazz, method, *args
5
- # @mail = UserMailer.welcome_email(User.find(1))
6
- @clazz = UserMailer
2
+
3
+ module JobDescribers
4
+ attr_accessor :object, :method, :args, :execute_at
5
+
6
+ def initialize object, method, *args
7
+ @object = object
7
8
  @method = method
8
9
  @args = args
9
10
  end
10
-
11
- def run
12
- @mail = @clazz.send @method, *@args
13
- @mail.deliver
14
- end
15
11
 
16
12
  def description
17
- desc = "Mailer: #{(@clazz || "nil")}."
18
- desc << "Method: #{(@method || nil)}."
19
- desc << "Args: #{(@args || nil)}"
13
+ desc = "Object: #{(@object || "nil")}."
14
+ desc << "Method: #{(@method || "nil")}."
15
+ desc << "Args: #{(@args || "nil")}"
20
16
  end
17
+ alias_method :inspect, :description
21
18
  end
22
19
 
23
- class BasicJob
24
- attr_accessor :object, :method, :args
25
- def initialize object, method, *args
26
- @object = object
27
- @method = method
28
- @args = args
29
- end
20
+ class MailerJob
21
+ include JobDescribers
30
22
 
31
23
  def run
32
- @object.send(:method, *@args)
24
+ @mail = @object.send @method, *@args
25
+ @mail.deliver
33
26
  end
27
+ end
34
28
 
35
- def description
36
- desc = "Object: #{(@object || "nil")}."
37
- desc << "Method: #{(@method || nil)}."
38
- desc << "Args: #{(@args || nil)}"
29
+ class BasicJob
30
+ include JobDescribers
31
+
32
+ def run
33
+ @object.send(@method, *@args)
39
34
  end
40
35
  end
36
+
41
37
  end
@@ -4,38 +4,20 @@ module Afterparty
4
4
  include Afterparty::QueueHelpers
5
5
 
6
6
  def push job
7
- # @mutex.synchronize do
8
- return nil if job.nil?
9
- queue_name = @temp_namespace || @options[:namespace]
10
- AfterpartyJob.make_with_job job, queue_name
11
- # end
7
+ return nil if job.nil?
8
+ AfterpartyJob.make_with_job job, @options[:namespace]
12
9
  end
13
10
  alias :<< :push
14
11
  alias :eng :push
15
12
 
16
13
  def pop
17
- # @mutex.synchronize do
18
- while true do
19
- unless (_job = AfterpartyJob.valid.first).nil?
20
- _job.save
21
- return _job
22
- end
23
- sleep(@options[:sleep])
14
+ while true do
15
+ unless (_job = next_valid_job).nil?
16
+ _job.save
17
+ return _job
24
18
  end
25
- # end
26
- end
27
- end
28
-
29
- class TestQueue < Queue
30
- attr_accessor :completed_jobs
31
-
32
- def initialize opts={}
33
- super
34
- @completed_jobs = []
35
- @exceptions = []
36
- end
37
- def handle_exception job, exception
38
- @exceptions << [job, exception]
19
+ sleep(@options[:sleep])
20
+ end
39
21
  end
40
22
  end
41
23
  end
@@ -1,5 +1,6 @@
1
1
  module Afterparty
2
2
  module QueueHelpers
3
+ attr_reader :options
3
4
 
4
5
  def initialize options = {}
5
6
  @options = options
@@ -9,12 +10,7 @@ module Afterparty
9
10
  self
10
11
  end
11
12
 
12
- def [] namespace
13
- @temp_namespace = namespace
14
- end
15
-
16
13
  def clear
17
- # redis_call :del
18
14
  AfterpartyJob.namespaced(@options[:namespace]).destroy_all
19
15
  end
20
16
 
@@ -22,10 +18,6 @@ module Afterparty
22
18
  AfterpartyJob.namespaced(@options[:namespace]).incomplete
23
19
  end
24
20
 
25
- def jobs_with_scores
26
- hash_from_scores(redis_call(:zrange, 0, -1, {withscores: true}))
27
- end
28
-
29
21
  def valid_jobs
30
22
  AfterpartyJob.namespaced(@options[:namespace]).valid
31
23
  end
@@ -50,11 +42,6 @@ module Afterparty
50
42
  AfterpartyJob.namespaced(@options[:namespace]).completed
51
43
  end
52
44
 
53
- def completed_with_scores
54
- @temp_namespace = "completed"
55
- hash_from_scores(redis_call(:zrange, -20, -1, withscores: true)).reverse
56
- end
57
-
58
45
  def run(job)
59
46
  real_job = job.reify
60
47
  if real_job
@@ -92,18 +79,5 @@ module Afterparty
92
79
  raise 'Must set queue.config_login to use dashboard' if @login_block.nil?
93
80
  @login_block.call(username, password)
94
81
  end
95
-
96
-
97
- private
98
-
99
- # returns true if job has an :execute_at value
100
- def job_valid? job
101
- job.respond_to?(:execute_at) && !job.execute_at.nil?
102
- end
103
-
104
- # return timestamp of :execute_at or current time
105
- def queue_time job
106
- time = job_valid?(job) ? job.execute_at.to_i : Time.now.to_i
107
- end
108
82
  end
109
83
  end
@@ -1,3 +1,3 @@
1
1
  module Afterparty
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -4,7 +4,6 @@ module Afterparty
4
4
 
5
5
  def consume
6
6
  @stopped = false
7
- # puts "starting worker with namespace [#{@options[:namespace]}]."
8
7
  @thread = Thread.new {
9
8
  consume_sync
10
9
  }
@@ -21,7 +20,7 @@ module Afterparty
21
20
  while !@stopped
22
21
  job = next_valid_job
23
22
  if job
24
- puts "Executing job: #{job.id}"
23
+ puts "Executing job: #{job.id}" if job.respond_to? :id
25
24
  run job
26
25
  else
27
26
  sleep(@options[:sleep])
@@ -5,5 +5,6 @@ class AfterpartyGenerator < Rails::Generators::Base
5
5
  def install
6
6
  copy_file "jobs_migration.rb", "db/migrate/#{Time.now.strftime('%Y%m%d%H%M%S')}_create_afterparty_jobs.rb"
7
7
  copy_file "initializer.rb", "config/initializers/afterparty.rb"
8
+ route "mount Afterparty::Engine, at: \"afterparty\", as: \"afterparty_engine\""
8
9
  end
9
10
  end
@@ -2,5 +2,5 @@ queue = Rails.configuration.queue = Afterparty::Queue.new
2
2
 
3
3
  queue.config_login do |username, password|
4
4
  # change this to something more secure!
5
- user == "admin" && password == "password"
5
+ username == "admin" && password == "password"
6
6
  end
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+
3
+ describe Afterparty do
4
+ describe "#load" do
5
+ it "should constantize any missing Classes while loading" do
6
+ obj = TestJob.new
7
+ dump = YAML.dump(obj)
8
+ YAML.stub(:load) do
9
+ YAML.unstub(:load)
10
+ raise ArgumentError, "undefined class/module TestJob"
11
+ end
12
+ String.any_instance.should_receive(:constantize).once
13
+ Afterparty.load(dump).should_not be_nil
14
+ end
15
+
16
+ it "returns nil when an exception is raised in YAML.load" do
17
+ YAML.stub(:load){ raise Exception }
18
+ Afterparty.load("anything").should be_nil
19
+ end
20
+ end
21
+
22
+ describe "#job_valid?" do
23
+ it "returns false unless job responds to #execute_at" do
24
+ job = {}
25
+ Afterparty.job_valid?(job).should be_false
26
+ end
27
+
28
+ it "returns false if #execute_at returns nil" do
29
+ job = TestJob.new
30
+ job.execute_at = nil
31
+ Afterparty.job_valid?(job).should be_false
32
+ end
33
+ end
34
+ end
@@ -1,10 +1,15 @@
1
1
  require 'spec_helper'
2
2
  describe :afterparty do
3
+ within_source_root do
4
+ FileUtils.mkdir_p "config"
5
+ FileUtils.touch "config/routes.rb"
6
+ end
3
7
  it "works" do
4
8
  subject.should generate(:copy_file, "jobs_migration.rb")
5
9
  subject.should generate("config/initializers/afterparty.rb") do |content|
6
10
  content.should include("Afterparty::Queue.new")
7
11
  content.should include("queue.config_login do |username, password|")
8
12
  end
13
+ subject.should generate(:route, "mount Afterparty::Engine, at: \"afterparty\", as: \"afterparty_engine\"")
9
14
  end
10
15
  end
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+
3
+ describe Afterparty::MailerJob do
4
+ class Mailer
5
+ def self.mail
6
+ self.new
7
+ end
8
+
9
+ def deliver
10
+ true
11
+ end
12
+ end
13
+
14
+ let(:job){ Afterparty::MailerJob.new Mailer, :mail }
15
+
16
+ it "initializes and sets the right attributes" do
17
+ job.args.should eq([])
18
+ job.object.should eq(Mailer)
19
+ job.method.should eq(:mail)
20
+ end
21
+
22
+ describe "description" do
23
+ it "describes correctly" do
24
+ description = "Object: Mailer.Method: mail.Args: []"
25
+ job.description.should eq(description)
26
+ end
27
+ end
28
+
29
+ it "calls #delivers on the mailer in when ran" do
30
+ Mailer.any_instance.should_receive(:deliver).once
31
+ job.run
32
+ end
33
+
34
+ end
35
+
36
+ describe Afterparty::BasicJob do
37
+ class Person
38
+ def say_hello name
39
+ "hello #{name}!"
40
+ end
41
+ end
42
+
43
+ ran = false
44
+ let(:job){ Afterparty::BasicJob.new(Person.new, :say_hello, "hank") }
45
+
46
+ it "initializes and sets the right attributes" do
47
+ job.args.should eq(["hank"])
48
+ job.object.should be_a(Person)
49
+ job.method.should eq(:say_hello)
50
+ end
51
+
52
+ it "sends the given method to @object with @args" do
53
+ Person.any_instance.should_receive(:say_hello).with("hank").once
54
+ job.run
55
+ end
56
+
57
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe Afterparty::JobContainer do
4
+ it "initializes correctly" do
5
+ job = TestJob.new
6
+ raw = YAML.dump(job)
7
+ container = Afterparty::JobContainer.new raw, Time.now.to_i
8
+ container.job.should be_a(TestJob)
9
+
10
+ container.job_class.should eq(TestJob)
11
+ end
12
+
13
+ it "sets job to nil if an error is thrown in YAML.load" do
14
+ Afterparty.stub(:load){ raise }
15
+ job = TestJob.new
16
+ raw = YAML.dump(job)
17
+ container = Afterparty::JobContainer.new raw, Time.now.to_i
18
+ container.job.should be_nil
19
+
20
+ container.job_class.should be_nil
21
+ end
22
+ end
@@ -53,4 +53,39 @@ describe Afterparty::QueueHelpers do
53
53
  @q.authenticate("userbad","pass").should == false
54
54
  @q.authenticate("user","passbad").should == false
55
55
  end
56
+
57
+ it "saves errors if a job can't reify" do
58
+ job = AfterpartyJob.make_with_job test_job
59
+ job.stub(:reify) { nil }
60
+ @q.run job
61
+ job.has_error.should be_true
62
+ job.error_message.should eq("Error marshaling job.")
63
+ end
64
+
65
+ it "handles exceptions when running a job" do
66
+ job = AfterpartyJob.make_with_job test_job
67
+ job.stub(:reify).and_raise(Exception, "message")
68
+ @q.should_receive(:handle_exception)
69
+ @q.run job
70
+ end
71
+
72
+ it "saves error data about a job when handling exceptions" do
73
+ job = AfterpartyJob.make_with_job test_job
74
+ job.stub(:reify).and_raise(Exception, "message")
75
+ @q.options[:logger].should_receive(:error)
76
+ @q.run job
77
+ job.completed.should be_true
78
+ job.completed_at.should be < DateTime.now
79
+ job.has_error.should be_true
80
+ job.error_message.should eq("message")
81
+ job.error_backtrace.should_not be_nil
82
+ end
83
+
84
+ it "returns the last completed job" do
85
+ job = AfterpartyJob.make_with_job test_job
86
+ job.completed = true
87
+ job.save
88
+ @q.last_completed.should eq(job)
89
+ @q.completed.should eq([job])
90
+ end
56
91
  end
@@ -46,4 +46,16 @@ describe Afterparty::Queue do
46
46
  (inner = wrapper.reify).name.should == "testy"
47
47
  wrapper.queue.should == "tester"
48
48
  end
49
+
50
+ it "should sleep if no jobs are valid on #pop" do
51
+ sleep_called = false
52
+ job = nil
53
+ @q.clear
54
+ @q.stub(:sleep) {
55
+ sleep_called = true
56
+ job = AfterpartyJob.make_with_job test_job
57
+ }
58
+ @q.pop
59
+ sleep_called.should be_true
60
+ end
49
61
  end
@@ -1,3 +1,14 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start do
9
+ add_filter "/spec/"
10
+ end
11
+
1
12
  require 'rubygems'
2
13
  require 'bundler/setup'
3
14
  require 'awesome_print'
@@ -5,6 +16,7 @@ require 'redis'
5
16
  require 'afterparty' # and any other gems you need
6
17
  require 'helpers'
7
18
  require 'genspec'
19
+ require 'fileutils'
8
20
 
9
21
  RSpec.configure do |config|
10
22
  # some (optional) config here
@@ -22,4 +34,4 @@ def clean_database!
22
34
  ActiveRecord::Base.connection.execute "DELETE FROM afterparty_jobs"
23
35
  end
24
36
 
25
- clean_database!
37
+ clean_database!
@@ -0,0 +1,48 @@
1
+ require "spec_helper"
2
+
3
+ describe Afterparty::Worker do
4
+ let(:worker) { Afterparty::Worker.new({sleep: 0.25}) }
5
+ after do
6
+ worker.stop
7
+ end
8
+
9
+ describe "consume" do
10
+ it "calls a new thread" do
11
+ Thread.should_receive(:new).once
12
+ worker.consume
13
+ end
14
+
15
+ it "calls consume_sync on itself" do
16
+ worker.should_receive(:consume_sync).once
17
+ worker.consume
18
+ sleep 0.25
19
+ end
20
+ end
21
+
22
+ describe "consume_sync" do
23
+ it "runs the next_valid_job" do
24
+ worker.instance_variable_set "@stopped", false
25
+ job = TestJob.new
26
+ worker.stub(:next_valid_job) {
27
+ worker.unstub(:next_valid_job)
28
+ worker.instance_variable_set "@stopped", true
29
+ job
30
+ }
31
+ worker.should_receive(:run).with(job)
32
+ worker.consume_sync
33
+ worker.stop
34
+ end
35
+
36
+ it "sleeps if there are no valid jobs" do
37
+ worker.instance_variable_set "@stopped", false
38
+ worker.stub(:next_valid_job) {
39
+ worker.unstub(:next_valid_job)
40
+ worker.instance_variable_set "@stopped", true
41
+ nil
42
+ }
43
+ worker.should_receive(:sleep).with(0.25)
44
+ worker.consume_sync
45
+ worker.stop
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: afterparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hank Stoever
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-21 00:00:00.000000000 Z
11
+ date: 2013-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: iconv
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
@@ -56,14 +56,14 @@ dependencies:
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: Rails 4 compatible queue with support for executing jobs later.
@@ -82,7 +82,6 @@ files:
82
82
  - README.md
83
83
  - Rakefile
84
84
  - afterparty.gemspec
85
- - afterparty_test.sqlite3
86
85
  - app/assets/javascripts/afterparty.js.coffee
87
86
  - app/assets/stylesheets/afterparty.css.sass
88
87
  - app/controllers/afterparty/dashboard_controller.rb
@@ -97,7 +96,6 @@ files:
97
96
  - lib/afterparty/jobs.rb
98
97
  - lib/afterparty/queue.rb
99
98
  - lib/afterparty/queue_helpers.rb
100
- - lib/afterparty/threaded_queue_consumer.rb
101
99
  - lib/afterparty/version.rb
102
100
  - lib/afterparty/worker.rb
103
101
  - lib/generators/afterparty_generator.rb
@@ -105,14 +103,18 @@ files:
105
103
  - lib/generators/templates/jobs_migration.rb
106
104
  - lib/tasks/tasks.rake
107
105
  - spec/afterparty_job_spec.rb
106
+ - spec/afterparty_spec.rb
108
107
  - spec/database.yml
109
108
  - spec/generators/afterparty_generator_spec.rb
109
+ - spec/helper_jobs_spec.rb
110
110
  - spec/helpers.rb
111
+ - spec/job_container_spec.rb
111
112
  - spec/queue_functional_spec.rb
112
113
  - spec/queue_helpers_spec.rb
113
114
  - spec/queue_spec.rb
114
115
  - spec/schema.rb
115
116
  - spec/spec_helper.rb
117
+ - spec/worker_spec.rb
116
118
  homepage: ''
117
119
  licenses:
118
120
  - MIT
@@ -123,28 +125,31 @@ require_paths:
123
125
  - lib
124
126
  required_ruby_version: !ruby/object:Gem::Requirement
125
127
  requirements:
126
- - - ! '>='
128
+ - - '>='
127
129
  - !ruby/object:Gem::Version
128
130
  version: '0'
129
131
  required_rubygems_version: !ruby/object:Gem::Requirement
130
132
  requirements:
131
- - - ! '>='
133
+ - - '>='
132
134
  - !ruby/object:Gem::Version
133
135
  version: '0'
134
136
  requirements: []
135
137
  rubyforge_project:
136
- rubygems_version: 2.0.3
138
+ rubygems_version: 2.0.6
137
139
  signing_key:
138
140
  specification_version: 4
139
141
  summary: Rails 4 compatible queue with support for executing jobs later.
140
142
  test_files:
141
143
  - spec/afterparty_job_spec.rb
144
+ - spec/afterparty_spec.rb
142
145
  - spec/database.yml
143
146
  - spec/generators/afterparty_generator_spec.rb
147
+ - spec/helper_jobs_spec.rb
144
148
  - spec/helpers.rb
149
+ - spec/job_container_spec.rb
145
150
  - spec/queue_functional_spec.rb
146
151
  - spec/queue_helpers_spec.rb
147
152
  - spec/queue_spec.rb
148
153
  - spec/schema.rb
149
154
  - spec/spec_helper.rb
150
- has_rdoc:
155
+ - spec/worker_spec.rb
Binary file
@@ -1,58 +0,0 @@
1
- module Afterparty
2
-
3
- # inspired by the rails 4 implementation:
4
- # https://github.com/rails/rails/blob/jobs/activesupport/lib/active_support/queueing.rb
5
-
6
- # The threaded consumer will run jobs in a background thread in
7
- # development mode or in a VM where running jobs on a thread in
8
- # production mode makes sense.
9
- #
10
- # When the process exits, the consumer pushes a nil onto the
11
- # queue and joins the thread, which will ensure that all jobs
12
- # are executed before the process finally dies.
13
- class ThreadedQueueConsumer
14
- attr_accessor :logger, :thread
15
-
16
- def initialize(queue, options = {})
17
- @queue = queue
18
- @logger = options[:logger]
19
- @fallback_logger = Logger.new($stderr)
20
- end
21
-
22
- def start
23
- @thread = Thread.new { consume }
24
- self
25
- end
26
-
27
- def shutdown
28
- @queue.push nil
29
- @thread.join
30
- end
31
-
32
- def drain
33
- while job = @queue.pop(true)
34
- job.run
35
- end
36
- rescue ThreadError
37
- end
38
-
39
- def consume
40
- while job = @queue.pop
41
- if @queue.respond_to? :completed_jobs
42
- @queue.completed_jobs << job
43
- end
44
- run job
45
- end
46
- end
47
-
48
- def run(job)
49
- job.run
50
- rescue Exception => exception
51
- handle_exception job, exception
52
- end
53
-
54
- def handle_exception(job, exception)
55
- (logger || @fallback_logger).error "Job Error: #{job.inspect}\n#{exception.message}\n#{exception.backtrace.join("\n")}"
56
- end
57
- end
58
- end