employer-activerecord 0.0.1 → 0.1
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.
- data/.pryrc +2 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/README.md +22 -3
- data/employer-activerecord.gemspec +1 -0
- data/lib/employer-activerecord/job.rb +15 -0
- data/lib/employer-activerecord/pipeline.rb +41 -0
- data/lib/employer-activerecord/version.rb +1 -1
- data/lib/generators/employer/active_record_generator.rb +14 -0
- data/lib/generators/employer/templates/migration.rb +13 -0
- data/spec/employer-activerecord/job_spec.rb +34 -0
- data/spec/employer-activerecord/pipeline_spec.rb +70 -0
- data/spec/spec_helper.rb +9 -0
- metadata +32 -3
data/.pryrc
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation -I. -rspec_helper
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# Employer::
|
1
|
+
# Employer::ActiveRecord [](https://travis-ci.org/mkremer/employer-activerecord)
|
2
2
|
|
3
|
-
|
3
|
+
ActiveRecord backend for Employer
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,26 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
Generate and run the migration to create the employer\_jobs tablein your
|
22
|
+
database:
|
23
|
+
|
24
|
+
```
|
25
|
+
rails g employer:active_record
|
26
|
+
bundle exec rake db:migrate
|
27
|
+
```
|
28
|
+
|
29
|
+
Ensure that your Employer configuration starts with something like the below:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require "./config/environment.rb"
|
33
|
+
require "employer-activerecord"
|
34
|
+
|
35
|
+
pipeline_backend Employer::ActiveRecord::Pipeline.new
|
36
|
+
```
|
37
|
+
|
38
|
+
If you're not using Rails then require whatever sets up your application's
|
39
|
+
environment instead of config/environment.rb before requiring
|
40
|
+
employer-activerecord.
|
22
41
|
|
23
42
|
## Contributing
|
24
43
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "active_record"
|
2
|
+
|
3
|
+
module Employer
|
4
|
+
module ActiveRecord
|
5
|
+
class Job < ::ActiveRecord::Base
|
6
|
+
self.table_name = "employer_jobs"
|
7
|
+
self.inheritance_column = "_type"
|
8
|
+
|
9
|
+
validates :state, presence: true
|
10
|
+
validates :type, presence: true
|
11
|
+
|
12
|
+
scope :free, where(state: :free)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Employer
|
4
|
+
module ActiveRecord
|
5
|
+
class Pipeline
|
6
|
+
def enqueue(job_hash)
|
7
|
+
job_attributes = {
|
8
|
+
type: job_hash[:class],
|
9
|
+
properties: job_hash[:attributes].to_json,
|
10
|
+
state: :free
|
11
|
+
}
|
12
|
+
|
13
|
+
Employer::ActiveRecord::Job.create!(job_attributes).id
|
14
|
+
end
|
15
|
+
|
16
|
+
def dequeue
|
17
|
+
if job = Employer::ActiveRecord::Job.free.order("created_at ASC").lock(true).first
|
18
|
+
job.state = :locked
|
19
|
+
job.save!
|
20
|
+
{id: job.id, class: job.type, attributes: JSON.parse(job.properties)}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear
|
25
|
+
Employer::ActiveRecord::Job.destroy_all
|
26
|
+
end
|
27
|
+
|
28
|
+
def complete(job)
|
29
|
+
Employer::ActiveRecord::Job.find(job.id, lock: true).destroy
|
30
|
+
end
|
31
|
+
|
32
|
+
def fail(job)
|
33
|
+
Employer::ActiveRecord::Job.find(job.id, lock: true).update_attributes(state: :failed)
|
34
|
+
end
|
35
|
+
|
36
|
+
def reset(job)
|
37
|
+
Employer::ActiveRecord::Job.find(job.id, lock: true).update_attributes(state: :free)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module Employer
|
4
|
+
class ActiveRecordGenerator < ::Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
extend ActiveRecord::Generators::Migration
|
7
|
+
|
8
|
+
source_paths << File.join(File.dirname(__FILE__), "templates")
|
9
|
+
|
10
|
+
def create_migration_file
|
11
|
+
migration_template 'migration.rb', 'db/migrate/create_employer_jobs.rb'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateEmployerJobs < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :employer_jobs do |t|
|
4
|
+
t.string :state
|
5
|
+
t.string :type
|
6
|
+
t.text :properties
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :employer_jobs, [:state, :created_at], order: {created_at: :asc}
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "employer-activerecord/job"
|
2
|
+
|
3
|
+
describe Employer::ActiveRecord::Job do
|
4
|
+
let(:job) { Employer::ActiveRecord::Job.new(state: :free, type: "TestJob") }
|
5
|
+
|
6
|
+
it "requires state" do
|
7
|
+
job.state = nil
|
8
|
+
job.should be_invalid
|
9
|
+
job.errors.should include(:state)
|
10
|
+
job.state = :free
|
11
|
+
job.should be_valid
|
12
|
+
end
|
13
|
+
|
14
|
+
it "requires type" do
|
15
|
+
job.type = nil
|
16
|
+
job.should be_invalid
|
17
|
+
job.errors.should include(:type)
|
18
|
+
job.type = "TestJob"
|
19
|
+
job.should be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
describe ".free" do
|
23
|
+
it "returns jobs with state free" do
|
24
|
+
job1 = Employer::ActiveRecord::Job.create(state: :free, type: "TestJob")
|
25
|
+
job2 = Employer::ActiveRecord::Job.create(state: :free, type: "TestJob")
|
26
|
+
job3 = Employer::ActiveRecord::Job.create(state: :locked, type: "TestJob")
|
27
|
+
|
28
|
+
free_jobs = Employer::ActiveRecord::Job.free.to_a
|
29
|
+
free_jobs.should include(job1)
|
30
|
+
free_jobs.should include(job2)
|
31
|
+
free_jobs.should_not include(job3)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "employer-activerecord/pipeline"
|
2
|
+
require "employer-activerecord/job"
|
3
|
+
|
4
|
+
describe Employer::ActiveRecord::Pipeline do
|
5
|
+
let(:pipeline) { Employer::ActiveRecord::Pipeline.new }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Employer::ActiveRecord::Job.destroy_all
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#enqueue" do
|
12
|
+
it "saves the job hash to the database" do
|
13
|
+
job_hash = {class: "TestJob", attributes: {shape: "Square", color: "Blue"}}
|
14
|
+
job_id = pipeline.enqueue(job_hash)
|
15
|
+
job = Employer::ActiveRecord::Job.find(job_id)
|
16
|
+
job.should_not be_nil
|
17
|
+
job.type.should eq("TestJob")
|
18
|
+
job.properties.should eq({"shape" => "Square", "color" => "Blue"}.to_json)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#dequeue" do
|
23
|
+
it "locks a job from the database and returns it as a job hash" do
|
24
|
+
locked_job = Employer::ActiveRecord::Job.create!(created_at: 2.days.ago, state: :locked, type: "TestJob", properties: {shape: "Circle", color: "Red"}.to_json)
|
25
|
+
free_job1 = Employer::ActiveRecord::Job.create!(created_at: 1.day.ago, state: :free, type: "TestJob", properties: {shape: "Triangle", color: "Green"}.to_json)
|
26
|
+
free_job2 = Employer::ActiveRecord::Job.create!(state: :free, type: "TestJob", properties: {shape: "Square", color: "Yellow"}.to_json)
|
27
|
+
|
28
|
+
job_hash = {id: free_job1.id, class: "TestJob", attributes: {"shape" => "Triangle", "color" => "Green"}}
|
29
|
+
pipeline.dequeue.should eq(job_hash)
|
30
|
+
|
31
|
+
job_hash = {id: free_job2.id, class: "TestJob", attributes: {"shape" => "Square", "color" => "Yellow"}}
|
32
|
+
pipeline.dequeue.should eq(job_hash)
|
33
|
+
|
34
|
+
pipeline.dequeue.should be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "clear" do
|
39
|
+
it "deletes all jobs" do
|
40
|
+
Employer::ActiveRecord::Job.should_receive(:destroy_all)
|
41
|
+
pipeline.clear
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#complete" do
|
46
|
+
it "deletes the job from the database" do
|
47
|
+
job = Employer::ActiveRecord::Job.create!(state: :free, type: "TestJob", properties: {shape: "Triangle", color: "Green"}.to_json)
|
48
|
+
pipeline.complete(job)
|
49
|
+
Employer::ActiveRecord::Job.where(id: job.id).count.should eq(0)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#reset" do
|
54
|
+
it "unlocks the job in the database" do
|
55
|
+
job = Employer::ActiveRecord::Job.create!(state: :locked, type: "TestJob", properties: {shape: "Triangle", color: "Green"}.to_json)
|
56
|
+
pipeline.reset(job)
|
57
|
+
job.reload
|
58
|
+
job.state.should eq("free")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#fail" do
|
63
|
+
it "marks the job as failed in the database" do
|
64
|
+
job = Employer::ActiveRecord::Job.create!(state: :locked, type: "TestJob", properties: {shape: "Triangle", color: "Green"}.to_json)
|
65
|
+
pipeline.fail(job)
|
66
|
+
job.reload
|
67
|
+
job.state.should eq("failed")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require "pry"
|
2
|
+
require "active_record"
|
3
|
+
require "generators/employer/templates/migration"
|
4
|
+
|
5
|
+
# Connect with an in-memory SQLite database
|
6
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
7
|
+
|
8
|
+
# Run the template migration to generate the jobs table
|
9
|
+
CreateEmployerJobs.new.change
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: employer-activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.1'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: employer
|
@@ -75,6 +75,22 @@ dependencies:
|
|
75
75
|
- - ! '>='
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: sqlite3
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
78
94
|
description:
|
79
95
|
email:
|
80
96
|
- mark@without-brains.net
|
@@ -83,13 +99,23 @@ extensions: []
|
|
83
99
|
extra_rdoc_files: []
|
84
100
|
files:
|
85
101
|
- .gitignore
|
102
|
+
- .pryrc
|
103
|
+
- .rspec
|
104
|
+
- .travis.yml
|
86
105
|
- Gemfile
|
87
106
|
- LICENSE.txt
|
88
107
|
- README.md
|
89
108
|
- Rakefile
|
90
109
|
- employer-activerecord.gemspec
|
91
110
|
- lib/employer-activerecord.rb
|
111
|
+
- lib/employer-activerecord/job.rb
|
112
|
+
- lib/employer-activerecord/pipeline.rb
|
92
113
|
- lib/employer-activerecord/version.rb
|
114
|
+
- lib/generators/employer/active_record_generator.rb
|
115
|
+
- lib/generators/employer/templates/migration.rb
|
116
|
+
- spec/employer-activerecord/job_spec.rb
|
117
|
+
- spec/employer-activerecord/pipeline_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
93
119
|
homepage:
|
94
120
|
licenses:
|
95
121
|
- MIT
|
@@ -115,5 +141,8 @@ rubygems_version: 1.8.23
|
|
115
141
|
signing_key:
|
116
142
|
specification_version: 3
|
117
143
|
summary: ActiveRecord backend for Employer
|
118
|
-
test_files:
|
144
|
+
test_files:
|
145
|
+
- spec/employer-activerecord/job_spec.rb
|
146
|
+
- spec/employer-activerecord/pipeline_spec.rb
|
147
|
+
- spec/spec_helper.rb
|
119
148
|
has_rdoc:
|