postjob 0.1.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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +23 -0
  3. data/bin/postjob +11 -0
  4. data/lib/postjob/cli/db.rb +39 -0
  5. data/lib/postjob/cli/job.rb +67 -0
  6. data/lib/postjob/cli/ps.rb +110 -0
  7. data/lib/postjob/cli/run.rb +19 -0
  8. data/lib/postjob/cli.rb +31 -0
  9. data/lib/postjob/error.rb +16 -0
  10. data/lib/postjob/job.rb +66 -0
  11. data/lib/postjob/migrations.rb +97 -0
  12. data/lib/postjob/queue/encoder.rb +40 -0
  13. data/lib/postjob/queue/notifications.rb +72 -0
  14. data/lib/postjob/queue/search.rb +82 -0
  15. data/lib/postjob/queue.rb +331 -0
  16. data/lib/postjob/registry.rb +52 -0
  17. data/lib/postjob/runner.rb +153 -0
  18. data/lib/postjob/workflow.rb +60 -0
  19. data/lib/postjob.rb +170 -0
  20. data/spec/postjob/enqueue_spec.rb +86 -0
  21. data/spec/postjob/full_workflow_spec.rb +86 -0
  22. data/spec/postjob/job_control/manual_spec.rb +45 -0
  23. data/spec/postjob/job_control/max_attempts_spec.rb +70 -0
  24. data/spec/postjob/job_control/timeout_spec.rb +31 -0
  25. data/spec/postjob/job_control/workflow_status_spec.rb +52 -0
  26. data/spec/postjob/process_job_spec.rb +25 -0
  27. data/spec/postjob/queue/encoder_spec.rb +46 -0
  28. data/spec/postjob/queue/search_spec.rb +141 -0
  29. data/spec/postjob/run_spec.rb +69 -0
  30. data/spec/postjob/step_spec.rb +26 -0
  31. data/spec/postjob/sub_workflow_spec.rb +27 -0
  32. data/spec/spec_helper.rb +35 -0
  33. data/spec/support/configure_active_record.rb +18 -0
  34. data/spec/support/configure_database.rb +19 -0
  35. data/spec/support/configure_simple_sql.rb +17 -0
  36. data/spec/support/connect_active_record.rb +6 -0
  37. data/spec/support/test_helper.rb +53 -0
  38. metadata +269 -0
@@ -0,0 +1,141 @@
1
+ require "spec_helper"
2
+
3
+ # rubocop:disable Metrics/BlockLength
4
+
5
+ module SearchWorkflow
6
+ def self.run
7
+ set_workflow_status "starting-up"
8
+
9
+ job = async :manual, timeout: 10
10
+ set_workflow_status "created-manual"
11
+
12
+ _token = workflow_token job
13
+ set_workflow_status "created-manual-token"
14
+
15
+ manual_result = await job
16
+ set_workflow_status "got-manual-token"
17
+
18
+ "manual-result:#{manual_result}"
19
+ end
20
+
21
+ Postjob.register_workflow self
22
+ end
23
+
24
+ describe "Postjob::Queue::Search" do
25
+ let!(:id) { Postjob.enqueue! "SearchWorkflow", tags: { "initial" => "yay" } }
26
+
27
+ include TestHelper
28
+
29
+ Search = Postjob::Queue::Search
30
+
31
+ before do
32
+ Postjob.process_all
33
+ end
34
+
35
+ def load_child_job
36
+ TestHelper.load_job "SELECT * FROM postjobs WHERE parent_id=$1", id
37
+ end
38
+
39
+ def token
40
+ load_token(load_child_job)
41
+ end
42
+
43
+ it "creates a token" do
44
+ expect! token => /[A-F0-9]{8}-[A-F0-9]{4}-[A-F0-9]{4}-[a-fA-F0-9]{4}-[A-F0-9]{12}/i
45
+ end
46
+
47
+ describe "returned data shape" do
48
+ it "returns a specific set of attributes" do
49
+ result = Search.one(id)
50
+ expected_keys = [
51
+ :id,
52
+ :full_id,
53
+ :job,
54
+ :workflow_status,
55
+ :status,
56
+ :error,
57
+ :result,
58
+ :next_run_at,
59
+ :error_backtrace,
60
+ :age,
61
+ :runtime,
62
+ :tags
63
+ ]
64
+ expect(result.keys).to contain_exactly(*expected_keys)
65
+ end
66
+ end
67
+
68
+ describe "search_one" do
69
+ it "can find a job by id" do
70
+ result = Search.one(id)
71
+ expect(result).to be_a(Hash)
72
+ expect(Search.one(id)[:id]).to eq(id)
73
+ end
74
+
75
+ it "writes into the into: type" do
76
+ result = Search.one(id, into: OpenStruct)
77
+ expect(result).to be_a(OpenStruct)
78
+ expect(result.id).to eq(id)
79
+ end
80
+ end
81
+
82
+ describe "search_all" do
83
+ it "can find a job by id" do
84
+ result = Search.all into: OpenStruct
85
+ expect(result.map(&:id)).to eq([id])
86
+ end
87
+
88
+ context "with multiple jobs" do
89
+ before do
90
+ Postjob.enqueue! "SearchWorkflow", tags: { "secondary" => "yay" }
91
+ end
92
+
93
+ it "returns all entries" do
94
+ result = Search.all into: OpenStruct
95
+ expect(result.length).to eq(2)
96
+ end
97
+
98
+ it "honors page and per arguments" do
99
+ result = Search.all into: OpenStruct, page: 0, per: 1
100
+ expect(result.length).to eq(1)
101
+ expect(result.first.id).to eq(id)
102
+
103
+ result = Search.all into: OpenStruct, page: 1, per: 1
104
+ expect(result.length).to eq(1)
105
+ expect(result.first.id).not_to eq(id)
106
+
107
+ result = Search.all into: OpenStruct, page: 2, per: 1
108
+ expect(result.length).to eq(0)
109
+
110
+ expect do
111
+ Search.all into: OpenStruct, page: -10
112
+ end.to raise_error(ArgumentError)
113
+
114
+ expect do
115
+ Search.all into: OpenStruct, per: -10
116
+ end.to raise_error(ArgumentError)
117
+ end
118
+
119
+ it "sorts by id" do
120
+ # Note that the second job has a id larger than the original job's id.
121
+ result = Search.all into: OpenStruct
122
+ expect(result.first.id).to eq(id)
123
+ end
124
+ end
125
+
126
+ describe "filtering" do
127
+ it "positive filters by tags" do
128
+ filter = { "initial" => "yay" }
129
+ result = Search.all filter: filter, into: OpenStruct
130
+ expect(result.length).to eq(1)
131
+ expect(result.first.id).to eq(id)
132
+ end
133
+
134
+ it "negative filters by tags" do
135
+ filter = { "initial" => "nay" }
136
+ result = Search.all filter: filter, into: OpenStruct
137
+ expect(result.length).to eq(0)
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,69 @@
1
+ # rubocop:disable Metrics/BlockLength
2
+
3
+ require "spec_helper"
4
+
5
+ module TwoLevelWorkflow
6
+ module StringWorker
7
+ def self.run
8
+ "my string"
9
+ end
10
+
11
+ Postjob.register_workflow self
12
+ end
13
+
14
+ def self.run
15
+ r = async StringWorker
16
+ await r
17
+ end
18
+
19
+ Postjob.register_workflow self
20
+ end
21
+
22
+ describe "Postjob.Postjob.process_all" do
23
+ include TestHelper
24
+
25
+ let!(:id) { Postjob.enqueue! "TwoLevelWorkflow" }
26
+
27
+ it "runs the job returning the result" do
28
+ expect(Postjob.process_all).to eq(3)
29
+ processed_job = load_job(id)
30
+ expect(processed_job.status).to eq("ok")
31
+ expect(processed_job.resolve).to eq("my string")
32
+ end
33
+
34
+ context "when scheduled to run in the future" do
35
+ before do
36
+ Simple::SQL.ask <<~SQL, id
37
+ UPDATE postjobs
38
+ SET next_run_at=next_run_at + interval '10 seconds'
39
+ WHERE id=$1
40
+ SQL
41
+ end
42
+
43
+ it "does not run the job" do
44
+ expect(Postjob.process_all).to eq(0)
45
+ processed_job = load_job(id)
46
+ # expect(processed_job.status).to eq("ready")
47
+ expect(processed_job.resolve).to eq(:pending)
48
+ end
49
+ end
50
+
51
+ context "when scheduled to time out" do
52
+ before do
53
+ Simple::SQL.ask <<~SQL, id
54
+ UPDATE postjobs
55
+ SET timing_out_at=next_run_at
56
+ WHERE id=$1
57
+ SQL
58
+ end
59
+
60
+ it "times out when job is running" do
61
+ Postjob.process_all
62
+ processed_job = load_job(id)
63
+
64
+ expect do
65
+ processed_job.resolve
66
+ end.to raise_error(Timeout::Error)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ module StepWorkflow
4
+ def self.run
5
+ "Foo"
6
+ end
7
+
8
+ Postjob.register_workflow self, version: "1.2"
9
+ end
10
+
11
+ describe "Postjob.step" do
12
+ include TestHelper
13
+
14
+ let!(:job_id) { Postjob.enqueue! "StepWorkflow" }
15
+
16
+ it "runs the job is there is one" do
17
+ processed_job = Postjob.step
18
+ expect(processed_job.id).to eq(job_id)
19
+ end
20
+
21
+ it "returns nil if there is none" do
22
+ Postjob.process_all
23
+ processed_job = Postjob.step
24
+ expect(processed_job).to be_nil
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ module SubWorkflow
4
+ def self.my_string
5
+ "my string"
6
+ end
7
+
8
+ def self.run
9
+ r = async :my_string
10
+ await r
11
+ end
12
+
13
+ Postjob.register_workflow self
14
+ end
15
+
16
+ describe "Sub Workflows" do
17
+ include TestHelper
18
+
19
+ let!(:id) { Postjob.enqueue! "SubWorkflow" }
20
+
21
+ it "runs the job returning the result" do
22
+ Postjob.process_all
23
+ processed_job = load_job(id)
24
+ expect(processed_job.status).to eq("ok")
25
+ expect(processed_job.resolve).to eq("my string")
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ ENV["RACK_ENV"] = "test"
2
+
3
+ require "rspec"
4
+ require "pry"
5
+ require "simplecov"
6
+ require "awesome_print"
7
+
8
+ unless ENV["SKIP_SIMPLE_COV"]
9
+ SimpleCov.start do
10
+ minimum_coverage 91
11
+ add_filter "/spec/"
12
+ end
13
+ end
14
+
15
+ require "postjob"
16
+ Postjob.fast_mode = true
17
+
18
+ logger = Logger.new("log/test.log")
19
+ logger.formatter = proc do |severity, _datetime, _progname, msg|
20
+ "#{severity}: #{msg}\n"
21
+ end
22
+ Simple::SQL.logger = Postjob.logger = logger
23
+
24
+ require "./spec/support/configure_database"
25
+ require "./spec/support/test_helper"
26
+
27
+ RSpec.configure do |config|
28
+ config.run_all_when_everything_filtered = true
29
+ config.filter_run focus: (ENV["CI"] != "true")
30
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
31
+ config.order = "random"
32
+
33
+ config.before(:all) {}
34
+ config.after {}
35
+ end
@@ -0,0 +1,18 @@
1
+ require "active_record"
2
+ ActiveRecord::Base.establish_connection(adapter: "postgresql",
3
+ database: "postjob_test",
4
+ username: "postjob",
5
+ password: "postjob")
6
+
7
+ # RSpec.configure do |config|
8
+ # config.around(:each) do |example|
9
+ # if example.metadata[:transactions] == false
10
+ # example.run
11
+ # else
12
+ # ::ActiveRecord::Base.connection.transaction do
13
+ # example.run
14
+ # raise ActiveRecord::Rollback, "clean up"
15
+ # end
16
+ # end
17
+ # end
18
+ # end
@@ -0,0 +1,19 @@
1
+ if ENV["USE_ACTIVE_RECORD"]
2
+ require_relative "configure_active_record"
3
+ else
4
+ require_relative "configure_simple_sql"
5
+ end
6
+
7
+ RSpec.configure do |config|
8
+ config.around(:each) do |example|
9
+ Simple::SQL.ask "DELETE FROM postjob.postjobs"
10
+ example.run
11
+ end
12
+ end
13
+
14
+ require "postjob/migrations"
15
+
16
+ Postjob::Migrations.unmigrate!
17
+ Postjob::Migrations.migrate!
18
+
19
+ Simple::SQL.ask "SET search_path = postjob, public, pg_catalog"
@@ -0,0 +1,17 @@
1
+ ENV["DATABASE_URL"] = "postgresql://postjob:postjob@localhost/postjob_test"
2
+ ::Simple::SQL.connect!
3
+
4
+ # RSpec.configure do |config|
5
+ # config.around(:each) do |example|
6
+ # if example.metadata[:transactions] == false
7
+ # example.run
8
+ # else
9
+ # catch(:rollback) do
10
+ # ::Simple::SQL.transaction do
11
+ # example.run
12
+ # throw :rollback
13
+ # end
14
+ # end
15
+ # end
16
+ # end
17
+ # end
@@ -0,0 +1,6 @@
1
+ require "active_record"
2
+ ActiveRecord::Base.establish_connection(adapter: "postgresql",
3
+ database: "postjob_test",
4
+ username: "postjob",
5
+ password: "postjob")
6
+
@@ -0,0 +1,53 @@
1
+ Postjob.send :public, :process_job
2
+
3
+ module TestHelper
4
+ extend self
5
+
6
+ def jobs_count
7
+ Simple::SQL.ask "SELECT count(*) FROM postjobs"
8
+ end
9
+
10
+ def newest_job
11
+ Simple::SQL.record "SELECT * FROM postjobs ORDER BY id DESC", into: Postjob::Job
12
+ end
13
+
14
+ def load_job(id_or_sql, *args)
15
+ case id_or_sql
16
+ when Integer
17
+ Simple::SQL.record "SELECT * FROM postjobs WHERE id=$1", id_or_sql, into: Postjob::Job
18
+ else
19
+ Simple::SQL.record id_or_sql, *args, into: Postjob::Job
20
+ end
21
+ end
22
+
23
+ def load_token(job)
24
+ Simple::SQL.ask "SELECT token FROM tokens WHERE postjob_id=$1", job.id
25
+ end
26
+
27
+ def print_sql(sql, *args)
28
+ require "table_print"
29
+
30
+ records = Simple::SQL.records(sql, *args)
31
+ tp records
32
+ end
33
+
34
+ def print_jobs
35
+ print_sql <<~SQL
36
+ SELECT
37
+ id,
38
+ workflow AS job,
39
+ workflow_method AS m,
40
+ args,
41
+ status,
42
+ (results->0)::varchar AS result,
43
+ failed_attempts AS attempts,
44
+ EXTRACT(EPOCH FROM ((now() at time zone 'utc') - created_at)) AS age,
45
+ EXTRACT(EPOCH FROM (next_run_at - (now() at time zone 'utc'))) AS next_run_in,
46
+ error,
47
+ error_message,
48
+ (error_backtrace->0)::varchar AS backtrace
49
+ FROM postjobs
50
+ ORDER BY id
51
+ SQL
52
+ end
53
+ end
metadata ADDED
@@ -0,0 +1,269 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: postjob
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - radiospiel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.5.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.7.1
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.7.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: timecop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: awesome_print
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simple-sql
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.2.5
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.2.5
153
+ - !ruby/object:Gem::Dependency
154
+ name: simple-cli
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '0.2'
160
+ - - ">="
161
+ - !ruby/object:Gem::Version
162
+ version: 0.2.4
163
+ type: :runtime
164
+ prerelease: false
165
+ version_requirements: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - "~>"
168
+ - !ruby/object:Gem::Version
169
+ version: '0.2'
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: 0.2.4
173
+ - !ruby/object:Gem::Dependency
174
+ name: table_print
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :runtime
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: expectation
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: 1.1.1
194
+ type: :runtime
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: 1.1.1
201
+ description: restartable, asynchronous, and distributed processes
202
+ email:
203
+ - radiospiel@open-lab.org
204
+ executables:
205
+ - postjob
206
+ extensions: []
207
+ extra_rdoc_files: []
208
+ files:
209
+ - README.md
210
+ - bin/postjob
211
+ - lib/postjob.rb
212
+ - lib/postjob/cli.rb
213
+ - lib/postjob/cli/db.rb
214
+ - lib/postjob/cli/job.rb
215
+ - lib/postjob/cli/ps.rb
216
+ - lib/postjob/cli/run.rb
217
+ - lib/postjob/error.rb
218
+ - lib/postjob/job.rb
219
+ - lib/postjob/migrations.rb
220
+ - lib/postjob/queue.rb
221
+ - lib/postjob/queue/encoder.rb
222
+ - lib/postjob/queue/notifications.rb
223
+ - lib/postjob/queue/search.rb
224
+ - lib/postjob/registry.rb
225
+ - lib/postjob/runner.rb
226
+ - lib/postjob/workflow.rb
227
+ - spec/postjob/enqueue_spec.rb
228
+ - spec/postjob/full_workflow_spec.rb
229
+ - spec/postjob/job_control/manual_spec.rb
230
+ - spec/postjob/job_control/max_attempts_spec.rb
231
+ - spec/postjob/job_control/timeout_spec.rb
232
+ - spec/postjob/job_control/workflow_status_spec.rb
233
+ - spec/postjob/process_job_spec.rb
234
+ - spec/postjob/queue/encoder_spec.rb
235
+ - spec/postjob/queue/search_spec.rb
236
+ - spec/postjob/run_spec.rb
237
+ - spec/postjob/step_spec.rb
238
+ - spec/postjob/sub_workflow_spec.rb
239
+ - spec/spec_helper.rb
240
+ - spec/support/configure_active_record.rb
241
+ - spec/support/configure_database.rb
242
+ - spec/support/configure_simple_sql.rb
243
+ - spec/support/connect_active_record.rb
244
+ - spec/support/test_helper.rb
245
+ homepage: https://github.com/radiospiel/postjob
246
+ licenses:
247
+ - MIT
248
+ metadata: {}
249
+ post_install_message:
250
+ rdoc_options: []
251
+ require_paths:
252
+ - lib
253
+ required_ruby_version: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ required_rubygems_version: !ruby/object:Gem::Requirement
259
+ requirements:
260
+ - - ">="
261
+ - !ruby/object:Gem::Version
262
+ version: '0'
263
+ requirements: []
264
+ rubyforge_project:
265
+ rubygems_version: 2.5.1
266
+ signing_key:
267
+ specification_version: 4
268
+ summary: restartable, asynchronous, and distributed processes
269
+ test_files: []