afterparty 0.0.21 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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