afterparty 0.0.21 → 0.1.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.
@@ -0,0 +1,3 @@
1
+ sqlite3:
2
+ adapter: sqlite3
3
+ database: afterparty_test.sqlite3
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ describe :afterparty do
3
+ it "works" do
4
+ subject.should generate(:copy_file, "jobs_migration.rb")
5
+ subject.should generate("config/initializers/afterparty.rb") do |content|
6
+ content.should include("Afterparty::Queue.new")
7
+ content.should include("queue.config_login do |username, password|")
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+ describe Afterparty::Queue do
3
+ before do
4
+ # require 'open-uri'
5
+ # uri = URI.parse("redis://localhost:6379")
6
+ # redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
7
+ # Afterparty.redis = redis
8
+ @q = Afterparty::TestQueue.new({sleep: 0.5, namespace: "master_test"})
9
+ end
10
+
11
+ after do
12
+ @worker.stop
13
+ end
14
+
15
+ before :each do
16
+ @worker = Afterparty::Worker.new({sleep: 0.5})
17
+ # @worker.consume
18
+ @q.clear
19
+ @job_time = (ENV['AFTERPARTY_JOB_TIME'] || 5).to_i
20
+ @slow_job_time = (ENV['AFTERPARTY_SLOW_TIME'] || 7).to_i
21
+ end
22
+
23
+ it "pushes nil without errors" do
24
+ @q.push(nil)
25
+ @q.jobs.should eq([])
26
+ end
27
+
28
+ it "adds items to the queue" do
29
+ lambda {
30
+ @q.push(test_job)
31
+ }.should change{ @q.total_jobs_count }.by(1)
32
+ end
33
+
34
+ it "executes the job" do
35
+ job = TestJob.new
36
+ @q.push(job)
37
+ lambda {
38
+ sleep(1)
39
+ @worker.consume_next
40
+ }.should change{ @q.total_jobs_count }.by(-1)
41
+ end
42
+
43
+ it "removes items from the queue after running them" do
44
+ @q.push TestJob.new
45
+ sleep(1)
46
+ @worker.consume_next
47
+ @q.jobs.size.should == 0
48
+ end
49
+
50
+ it "doesn't execute jobs that execute in a while" do
51
+ job = TestJob.new
52
+ job.execute_at = Time.now + 200
53
+ @q.push job
54
+ lambda {
55
+ @worker.consume_next
56
+ }.should change{ @q.total_jobs_count }.by(0)
57
+ # @q.jobs.size.should eq(1)
58
+ end
59
+
60
+ it "waits the correct amount of time to execute a job" do
61
+ job = TestJob.new
62
+ job.execute_at = Time.now + 4
63
+ @q.push(job)
64
+ sleep(1)
65
+ @q.jobs.size.should eq(1)
66
+ chill(@slow_job_time)
67
+ @worker.consume_next
68
+ @q.jobs.size.should eq(0)
69
+ end
70
+
71
+ it "doesn't wait and execute the job synchronously when added" do
72
+ job = test_job 100
73
+ t = Time.now
74
+ @q.push(job)
75
+ (Time.now - t).should <= 1
76
+ end
77
+
78
+ it "executes jobs in the right order" do
79
+ late_job = test_job 60*10
80
+ early_job = test_job
81
+ @q.push(late_job)
82
+ @q.push(early_job)
83
+ sleep(1)
84
+ @worker.consume_next
85
+ (jobs = @q.jobs).size.should eq(1)
86
+ jobs[0].execute_at.should_not be(nil)
87
+ end
88
+
89
+ class ErrorJob
90
+ attr_accessor :execute_at
91
+
92
+ def run
93
+ raise "hello"
94
+ end
95
+ end
96
+
97
+ def complete
98
+ @q.completed_jobs
99
+ end
100
+
101
+ def error_job later=nil
102
+ job = ErrorJob.new
103
+ job.execute_at = DateTime.now + later if later
104
+ job
105
+ end
106
+
107
+ def chill seconds
108
+ t = Time.now
109
+ while Time.now < (t + seconds); end
110
+ end
111
+
112
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ describe Afterparty::QueueHelpers do
3
+ before do
4
+ @q = Afterparty::Queue.new
5
+ end
6
+
7
+ before :each do
8
+ AfterpartyJob.destroy_all
9
+ end
10
+
11
+ it "destroys all jobs with with #clear" do
12
+ AfterpartyJob.make_with_job test_job(10)
13
+ AfterpartyJob.count.should == 1
14
+ @q.clear
15
+ AfterpartyJob.count.should == 0
16
+ end
17
+
18
+ it "returns incomplete jobs on #jobs" do
19
+ a = AfterpartyJob.make_with_job test_job(20)
20
+ b = AfterpartyJob.make_with_job test_job
21
+ @q.jobs.to_a.should == [b, a]
22
+ end
23
+
24
+ it "doesn't return incomplete jobs on #valid_jobs" do
25
+ a = AfterpartyJob.make_with_job test_job(20)
26
+ b = AfterpartyJob.make_with_job test_job
27
+ @q.valid_jobs.to_a.should == [b]
28
+ end
29
+
30
+ it "returns the next valid job" do
31
+ a = AfterpartyJob.make_with_job test_job(20)
32
+ b = AfterpartyJob.make_with_job test_job
33
+ c = AfterpartyJob.make_with_job test_job
34
+ @q.next_valid_job.should == b
35
+ end
36
+
37
+ it "correctly returns whether there are no valid jobs" do
38
+ AfterpartyJob.make_with_job test_job(20)
39
+ @q.jobs_empty?.should == true
40
+ end
41
+
42
+ it "correctly returns the total number of incomplete jobs" do
43
+ AfterpartyJob.make_with_job test_job(20)
44
+ @q.total_jobs_count.should == 1
45
+ end
46
+
47
+ it "configures dashboard login successfully" do
48
+ expect{ @q.authenticate("user", "pass") }.to raise_exception
49
+ @q.config_login do |username, password|
50
+ username == "user" && password == "pass"
51
+ end
52
+ @q.authenticate("user","pass").should == true
53
+ @q.authenticate("userbad","pass").should == false
54
+ @q.authenticate("user","passbad").should == false
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ ActiveRecord::Schema.define version: 0 do
2
+ create_table "afterparty_jobs", force: true do |t|
3
+ t.text :job_dump
4
+ t.string :queue
5
+ t.datetime :execute_at
6
+ t.boolean :completed
7
+ t.boolean :has_error
8
+ t.text :error_message
9
+ t.text :error_backtrace
10
+ t.datetime :completed_at
11
+
12
+ t.datetime :created_at
13
+ end
14
+ end
@@ -4,8 +4,22 @@ require 'awesome_print'
4
4
  require 'redis'
5
5
  require 'afterparty' # and any other gems you need
6
6
  require 'helpers'
7
+ require 'genspec'
7
8
 
8
9
  RSpec.configure do |config|
9
10
  # some (optional) config here
10
11
  config.include Afterparty::QueueTestHelpers
11
- end
12
+ end
13
+
14
+ database_yml = File.expand_path("../database.yml", __FILE__)
15
+ active_record_config = YAML.load_file(database_yml)
16
+ ActiveRecord::Base.configurations = active_record_config
17
+ ActiveRecord::Base.establish_connection("sqlite3")
18
+
19
+ load(File.dirname(__FILE__) + "/schema.rb")
20
+
21
+ def clean_database!
22
+ ActiveRecord::Base.connection.execute "DELETE FROM afterparty_jobs"
23
+ end
24
+
25
+ clean_database!
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: afterparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.1.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-14 00:00:00.000000000 Z
11
+ date: 2013-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: iconv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -68,14 +82,34 @@ files:
68
82
  - README.md
69
83
  - Rakefile
70
84
  - afterparty.gemspec
85
+ - afterparty_test.sqlite3
86
+ - app/assets/javascripts/afterparty.js.coffee
87
+ - app/assets/stylesheets/afterparty.css.sass
88
+ - app/controllers/afterparty/dashboard_controller.rb
89
+ - app/views/afterparty/dashboard/index.html.haml
90
+ - config/routes.rb
71
91
  - dump.rdb
72
92
  - lib/afterparty.rb
93
+ - lib/afterparty/afterparty_job.rb
94
+ - lib/afterparty/engine.rb
95
+ - lib/afterparty/job_container.rb
96
+ - lib/afterparty/jobs.rb
97
+ - lib/afterparty/queue.rb
73
98
  - lib/afterparty/queue_helpers.rb
74
- - lib/afterparty/redis_queue.rb
75
99
  - lib/afterparty/threaded_queue_consumer.rb
76
100
  - lib/afterparty/version.rb
101
+ - lib/afterparty/worker.rb
102
+ - lib/generators/afterparty_generator.rb
103
+ - lib/generators/templates/initializer.rb
104
+ - lib/generators/templates/jobs_migration.rb
105
+ - lib/tasks/tasks.rake
106
+ - spec/afterparty_job_spec.rb
107
+ - spec/database.yml
108
+ - spec/generators/afterparty_generator_spec.rb
77
109
  - spec/helpers.rb
78
- - spec/redis_queue_spec.rb
110
+ - spec/queue_functional_spec.rb
111
+ - spec/queue_helpers_spec.rb
112
+ - spec/schema.rb
79
113
  - spec/spec_helper.rb
80
114
  homepage: ''
81
115
  licenses:
@@ -102,7 +136,12 @@ signing_key:
102
136
  specification_version: 4
103
137
  summary: Rails 4 compatible queue with support for executing jobs later.
104
138
  test_files:
139
+ - spec/afterparty_job_spec.rb
140
+ - spec/database.yml
141
+ - spec/generators/afterparty_generator_spec.rb
105
142
  - spec/helpers.rb
106
- - spec/redis_queue_spec.rb
143
+ - spec/queue_functional_spec.rb
144
+ - spec/queue_helpers_spec.rb
145
+ - spec/schema.rb
107
146
  - spec/spec_helper.rb
108
147
  has_rdoc:
@@ -1,57 +0,0 @@
1
- module Afterparty
2
- class RedisQueue
3
- attr_accessor :redis, :options, :temp_namespace, :consumer
4
- include Afterparty::QueueHelpers
5
-
6
- def initialize options={}, consumer_options={}
7
- @consumer = ThreadedQueueConsumer.new(self, consumer_options).start
8
- @options = options
9
- @options[:namespace] ||= "default"
10
- @options[:sleep] ||= 5
11
- @mutex = Mutex.new
12
- end
13
-
14
- def push job
15
- @mutex.synchronize do
16
- return nil if job.nil?
17
- async_redis_call{ redis_call :zadd, queue_time(job), Marshal.dump(job) }
18
- @consumer.start unless @consumer.thread.alive?
19
- @temp_namespace = nil
20
- end
21
- end
22
- alias :<< :push
23
- alias :eng :push
24
-
25
- def pop
26
- @mutex.synchronize do
27
- while true do
28
- if jobs_empty?
29
- @consumer.shutdown
30
- elsif !(_jobs = valid_jobs).empty?
31
- job_dump = _jobs[0]
32
- async_redis_call do
33
- redis_call :zrem, job_dump
34
- @temp_namespace = "completed"
35
- redis_call :zadd, Time.now.to_i, job_dump
36
- end
37
- return Marshal.load(job_dump)
38
- end
39
- sleep(@options[:sleep])
40
- end
41
- end
42
- end
43
- end
44
-
45
- class TestRedisQueue < RedisQueue
46
- attr_accessor :completed_jobs
47
-
48
- def initialize opts={}, consumer_opts={}
49
- super
50
- @completed_jobs = []
51
- @exceptions = []
52
- end
53
- def handle_exception job, exception
54
- @exceptions << [job, exception]
55
- end
56
- end
57
- end
@@ -1,98 +0,0 @@
1
- require 'spec_helper'
2
- describe Afterparty::RedisQueue do
3
- before do
4
- require 'open-uri'
5
- uri = URI.parse("redis://localhost:6379")
6
- redis = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
7
- Afterparty.redis = redis
8
- @q = Afterparty::TestRedisQueue.new({sleep: 0.5})
9
- end
10
-
11
- before :each do
12
- @q.completed_jobs.clear
13
- @q.clear
14
- Afterparty.redis.quit
15
- @job_time = 10
16
- end
17
-
18
- it "pushes nil without errors" do
19
- @q.push(nil)
20
- @q.jobs.should eq([])
21
- end
22
-
23
- it "adds items to the queue" do
24
- @q.push(test_job)
25
- @q.total_jobs_count.should eq(1)
26
- end
27
-
28
- it "executes the job" do
29
- job = TestJob.new
30
- @q.push(job)
31
- complete.size.should eq(0)
32
- chill(@job_time)
33
- complete.size.should eq(1)
34
- end
35
-
36
- it "removes items from the queue after running them" do
37
- @q.push TestJob.new
38
- chill(@job_time)
39
- @q.jobs.should_not include(@job)
40
- end
41
-
42
- it "doesn't execute jobs that execute in a while" do
43
- job = TestJob.new
44
- job.execute_at = Time.now + 200
45
- @q.push job
46
- chill(@job_time)
47
- complete.size.should eq(0)
48
- end
49
-
50
- it "waits the correct amount of time to execute a job" do
51
- job = TestJob.new
52
- job.execute_at = Time.now + 2
53
- @q.push(job)
54
- chill(50)
55
- complete.size.should eq(1)
56
- end
57
-
58
- it "doesn't execute the job synchronously when added" do
59
- job = test_job 100
60
- t = Time.now
61
- @q.push(job)
62
- (Time.now - t).should <= 1
63
- end
64
-
65
- it "executes jobs in the right order" do
66
- late_job = test_job 60*10
67
- early_job = test_job
68
- @q.push(late_job)
69
- @q.push(early_job)
70
- chill(@job_time)
71
- complete.size.should eq(1)
72
- complete[0].execute_at.should be(nil)
73
- end
74
-
75
- class ErrorJob
76
- attr_accessor :execute_at
77
-
78
- def run
79
- raise "hello"
80
- end
81
- end
82
-
83
- def complete
84
- @q.completed_jobs
85
- end
86
-
87
- def error_job later=nil
88
- job = ErrorJob.new
89
- job.execute_at = Time.now + later if later
90
- job
91
- end
92
-
93
- def chill seconds
94
- t = Time.now
95
- while Time.now < (t + seconds); end
96
- end
97
-
98
- end