faktory_worker_ruby 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 672affacf993528eedff478961a96bbc222e62bc
4
- data.tar.gz: 8b58b6e46e4d6965690bc4a17f3067548671edd0
2
+ SHA256:
3
+ metadata.gz: 7739220174ff556abdf6a357cbcd260b6290c732628b27c8dc01ad00be727dd9
4
+ data.tar.gz: 3c87db6e71078419a761c6b34dbdcdd3914d5551f4b42f04140a1621c6568b50
5
5
  SHA512:
6
- metadata.gz: 7210a8933baf0a671a608d41b5bb183fec3ea93b5c233c937c3882e921634d1baedb5985be1ecd6142ee1ca9257d3483012a7511f40c4f58fc4c13d0f34a4f4f
7
- data.tar.gz: 1a2e769ad7b96d539842e29c7056e36523d878cb81ccda8610247b99e8f239877dfbe7caee93be6d194213801c2a31fbfb876c69f5a5850bad6b15461661c4e4
6
+ metadata.gz: b2fc14441abfab58c7cde5401e42adcfe3bb558cd5d5dbf8f6a5db6b176cf2b1d9057370dd0b1daf3d3ca629bb829495bc53167e56e02f0543ec4f89556792ba
7
+ data.tar.gz: 12b5d2fc13701e3c221b9ef8301bdb5b43806b1058336298393b66fc3f8020eb01d9569a43884a9f789a5df754bd24e987a340a74f12f055ae71a244d0d0763d
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ sudo: required
2
+
3
+ language: ruby
4
+
5
+ services:
6
+ - docker
7
+
8
+ before_install:
9
+ - docker pull contribsys/faktory:latest
10
+ - docker run -d -p 127.0.0.1:7419:7419 -p 127.0.0.1:7420:7420 contribsys/faktory:latest /faktory -b :7419 -w :7420
11
+ - docker ps -a
data/Changes.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changes
2
2
 
3
+ ## 1.0.1
4
+
5
+ - Run client middleware before pushing a job to Faktory [#48]
6
+ - Implement read timeouts for Faktory::Client for faktory#297
7
+
8
+ ## 1.0.0
9
+
10
+ - Ruby 2.5+ is now required
11
+ - Support for Faktory Enterprise, job batches and job tracking
12
+ - Support for the MUTATE command.
13
+ - Notify Faktory when a worker process is going quiet so that the UI shows this
14
+ - Refactor Faktory::Client error handling for faktory#208
15
+
16
+ ## 0.8.1
17
+
18
+ - Fix breakage with non-ActiveJobs [#29]
19
+ - Ruby 2.3+ is now required
20
+
21
+ ## 0.8.0
22
+
23
+ - Add `-l LABEL` argument for adding labels to a process [#27, jpwinans]
24
+ - Support the quiet and shutdown heartbeat signals from the server [#28]
25
+
26
+ ## 0.7.1
27
+
28
+ - Add an ActiveJob adapter for FWR. [#17, jagthedrummer]
29
+
3
30
  ## 0.7.0
4
31
 
5
32
  - Add testing API, almost identical to Sidekiq's `sidekiq/testing` API.
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'simplecov', require: false, group: :test
4
+
3
5
  gemspec
data/Gemfile.lock CHANGED
@@ -1,25 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- faktory_worker_ruby (0.7.0)
5
- connection_pool (~> 2.2, >= 2.2.1)
4
+ faktory_worker_ruby (1.0.1)
5
+ connection_pool (~> 2.2, >= 2.2.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- connection_pool (2.2.1)
11
- minitest (5.10.3)
12
- minitest-hooks (1.4.2)
13
- rake (12.1.0)
10
+ activejob (6.0.3.2)
11
+ activesupport (= 6.0.3.2)
12
+ globalid (>= 0.3.6)
13
+ activesupport (6.0.3.2)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (>= 0.7, < 2)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ zeitwerk (~> 2.2, >= 2.2.2)
19
+ concurrent-ruby (1.1.6)
20
+ connection_pool (2.2.3)
21
+ docile (1.3.2)
22
+ globalid (0.4.2)
23
+ activesupport (>= 4.2.0)
24
+ i18n (1.8.5)
25
+ concurrent-ruby (~> 1.0)
26
+ minitest (5.14.1)
27
+ minitest-hooks (1.5.0)
28
+ minitest (> 5.3)
29
+ rake (13.0.1)
30
+ simplecov (0.18.5)
31
+ docile (~> 1.1)
32
+ simplecov-html (~> 0.11)
33
+ simplecov-html (0.12.2)
34
+ thread_safe (0.3.6)
35
+ tzinfo (1.2.7)
36
+ thread_safe (~> 0.1)
37
+ zeitwerk (2.4.0)
14
38
 
15
39
  PLATFORMS
16
40
  ruby
17
41
 
18
42
  DEPENDENCIES
43
+ activejob (>= 5.2.0)
19
44
  faktory_worker_ruby!
20
45
  minitest (~> 5)
21
46
  minitest-hooks
22
- rake (~> 12)
47
+ rake
48
+ simplecov
23
49
 
24
50
  BUNDLED WITH
25
- 1.16.0
51
+ 2.1.4
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # faktory\_worker\_ruby
2
2
 
3
+ ![travis](https://travis-ci.org/contribsys/faktory_worker_ruby.svg?branch=master)
4
+
3
5
  Faktory\_worker\_ruby is the official Ruby client and worker process for the
4
6
  Faktory background job server. It is similar to [Sidekiq](http://sidekiq.org).
5
7
 
@@ -15,7 +17,7 @@ Faktory background job server. It is similar to [Sidekiq](http://sidekiq.org).
15
17
  +-----------------+ +-------------------+
16
18
  | | | |
17
19
  | Client | | Worker |
18
- | pushes | | pulls |
20
+ | pushes | | fetches |
19
21
  | jobs | | jobs |
20
22
  | | | |
21
23
  | | | |
@@ -30,11 +32,14 @@ Faktory background job server. It is similar to [Sidekiq](http://sidekiq.org).
30
32
  This gem contains only the client and worker parts. The
31
33
  server part is [here](https://github.com/contribsys/faktory/)
32
34
 
33
- ## Installation
35
+ ## Requirements
34
36
 
35
- First, make sure you have the [Faktory server](https://github.com/contribsys/faktory/#installation) installed.
37
+ * Ruby 2.5 or higher
38
+ * Faktory 1.2 or higher [Installation](https://github.com/contribsys/faktory/wiki/Installation)
36
39
 
37
- Next, install this gem:
40
+ Optionally, Rails 5.2+ for ActiveJob.
41
+
42
+ ## Installation
38
43
 
39
44
  gem install faktory_worker_ruby
40
45
 
@@ -92,4 +97,4 @@ PRs to improve this are very welcome).
92
97
 
93
98
  ## Author
94
99
 
95
- Mike Perham, @mperham, mike @ contribsys.com
100
+ Mike Perham, @getajobmike, mike @ contribsys.com
@@ -14,10 +14,11 @@ Gem::Specification.new do |gem|
14
14
  gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
15
15
  gem.test_files = []
16
16
  gem.version = Faktory::VERSION
17
- gem.required_ruby_version = ">= 2.2.2"
17
+ gem.required_ruby_version = ">= 2.5.0"
18
18
 
19
- gem.add_dependency 'connection_pool', '~> 2.2', ">= 2.2.1"
19
+ gem.add_dependency 'connection_pool', '~> 2.2', ">= 2.2.2"
20
+ gem.add_development_dependency 'activejob', '>= 5.2.0'
20
21
  gem.add_development_dependency 'minitest', '~> 5'
21
22
  gem.add_development_dependency 'minitest-hooks'
22
- gem.add_development_dependency 'rake', '~> 12'
23
+ gem.add_development_dependency 'rake'
23
24
  end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_job'
4
+
5
+ module ActiveJob
6
+ module QueueAdapters
7
+ # == Faktory adapter for Active Job
8
+ #
9
+ # To use Faktory set the queue_adapter config to +:faktory+.
10
+ #
11
+ # Rails.application.config.active_job.queue_adapter = :faktory
12
+ class FaktoryAdapter
13
+ def enqueue(job) #:nodoc:
14
+ enqueue_at(job, nil)
15
+ end
16
+
17
+ def enqueue_at(job, timestamp) #:nodoc:
18
+ jid = SecureRandom.hex(12)
19
+ job.provider_job_id = jid
20
+ hash = {
21
+ "jid" => jid,
22
+ "jobtype" => JobWrapper.to_s,
23
+ "custom" => {
24
+ "wrapped" => job.class.to_s,
25
+ },
26
+ "queue" => job.queue_name,
27
+ "args" => [ job.serialize ],
28
+ }
29
+ opts = job.faktory_options_hash.dup
30
+ hash["at"] = Time.at(timestamp).utc.to_datetime.rfc3339(9) if timestamp
31
+ if opts.size > 0
32
+ hash["retry"] = opts.delete("retry") if opts.has_key?("retry")
33
+ hash["custom"] = opts.merge(hash["custom"])
34
+ end
35
+ pool = Thread.current[:faktory_via_pool] || Faktory.server_pool
36
+ Faktory.client_middleware.invoke(hash, pool) do
37
+ pool.with do |c|
38
+ c.push(hash)
39
+ end
40
+ end
41
+ end
42
+
43
+ class JobWrapper #:nodoc:
44
+ include Faktory::Job
45
+
46
+ def perform(job_data)
47
+ Base.execute job_data
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ class Base
54
+ class_attribute :faktory_options_hash
55
+ self.faktory_options_hash = {}
56
+
57
+ def self.faktory_options(hsh)
58
+ self.faktory_options_hash = self.faktory_options_hash.stringify_keys.merge(hsh.stringify_keys)
59
+ end
60
+ end
61
+ end
data/lib/faktory.rb CHANGED
@@ -52,6 +52,7 @@ module Faktory
52
52
  # config.worker_middleware do |chain|
53
53
  # chain.add MyServerHook
54
54
  # end
55
+ # config.default_job_options = { retry: 3 }
55
56
  # end
56
57
  def self.configure_worker
57
58
  yield self if worker?
@@ -61,7 +62,7 @@ module Faktory
61
62
  # Configuration for Faktory client, use like:
62
63
  #
63
64
  # Faktory.configure_client do |config|
64
- # config.faktory = { :size => 1, :url => 'myhost:7419' }
65
+ # config.default_job_options = { retry: 3 }
65
66
  # end
66
67
  def self.configure_client
67
68
  yield self unless worker?
@@ -164,3 +165,4 @@ module Faktory
164
165
  end
165
166
 
166
167
  require 'faktory/rails' if defined?(::Rails::Engine)
168
+ require 'faktory/batch'
@@ -0,0 +1,178 @@
1
+ require "faktory/middleware/batch"
2
+
3
+ module Faktory
4
+ ##
5
+ # A Batch is a set of jobs which can be tracked as a group, with
6
+ # callbacks that can fire after all the jobs are attempted or successful.
7
+ # Every batch must define at least one callback.
8
+ #
9
+ # * The "complete" callback is fired when all jobs in the batch have been attempted.
10
+ # Some might have failed.
11
+ # * The "success" callback is fired when all jobs in the batch have succeeded. This
12
+ # might never be fired if a job continues to error until it runs out of retries.
13
+ #
14
+ # **Please note that batches are only available in Faktory Enterprise.** This is
15
+ # the client-side code required to implement batches, it won't work without
16
+ # the server-side component.
17
+ #
18
+ # Simple example:
19
+ #
20
+ # b = Faktory::Batch.new
21
+ # b.description = "Process all documents for user 12345"
22
+ # # a callback can be defined as just a Ruby job class
23
+ # b.success = "MySuccessCallbackJob"
24
+ # # or the full job hash...
25
+ # b.complete = { jobtype: "MyCompleteCallbackJob", args: [12345], queue: "critical" }
26
+ # b.jobs do
27
+ # SomeJob.perform_async(xyz)
28
+ # AnotherJob.perform_async(user_id)
29
+ # end
30
+ #
31
+ # At the end of the `jobs` call, the batch is persisted to the Faktory server. It must
32
+ # not be modified further with one exception: jobs within the batch can "reopen" the batch
33
+ # in order to dynamically add more jobs or child batches.
34
+ #
35
+ # Any job within a batch may "reopen" its own batch to dynamically add more jobs.
36
+ # A job can get access to its batch by using the `bid` or `batch` accessor on
37
+ # `Faktory::Job`. You can use the `bid` accessor to test if the job is part of a batch.
38
+ #
39
+ # Reopen example:
40
+ #
41
+ # class MyJob
42
+ # include Faktory::Job
43
+ #
44
+ # def perform
45
+ # batch.jobs do
46
+ # SomeOtherJob.perform_async
47
+ # end if bid
48
+ # end
49
+ #
50
+ # Batches may be nested without limit by setting `parent_bid` when creating a
51
+ # batch. Generally you create child batches if you wish that subset of jobs to have
52
+ # their own callback for your application logic purposes. Otherwise you can reopen the
53
+ # current batch and add more jobs.
54
+ #
55
+ # Batch parent/child relationship is never implicit: you must manually set
56
+ # `parent_bid` if you wish to define a child batch.
57
+ #
58
+ # Nested example:
59
+ #
60
+ # class MyJob
61
+ # include Faktory::Job
62
+ #
63
+ # def perform
64
+ # child = Faktory::Batch.new
65
+ #
66
+ # # MyJob is executing as part of a previously defined batch.
67
+ # # Add a new child batch to this batch.
68
+ # child.parent_bid = bid
69
+ # child.success = ...
70
+ # child.jobs do |cb|
71
+ # SomeJob.perform_async
72
+ #
73
+ # gchild = Faktory::Batch.new
74
+ # gchild.parent_bid = cb.bid
75
+ # gchild.success = ...
76
+ # gchild.jobs do |gcb|
77
+ # ChildJob.perform_async
78
+ # end
79
+ # end
80
+ # end
81
+ # end
82
+ #
83
+ # Callbacks are guaranteed to be called hierarchically: child's success callback
84
+ # will not be called until gchild's success callback has executed successfully.
85
+ #
86
+ class Batch
87
+ attr_reader :bid
88
+ attr_accessor :description, :parent_bid
89
+
90
+ def initialize(bid=nil)
91
+ @bid = bid
92
+ end
93
+
94
+ def success=(val)
95
+ raise "Batch cannot be modified once created" if bid
96
+ @success = to_callback(val)
97
+ end
98
+
99
+ def complete=(val)
100
+ raise "Batch cannot be modified once created" if bid
101
+ @success = to_callback(val)
102
+ end
103
+
104
+ def jobs(&block)
105
+ Faktory.server do |client|
106
+ if @bid.nil?
107
+ @bid = client.create_batch(self, &block)
108
+ else
109
+ client.reopen_batch(self, &block)
110
+ end
111
+ end
112
+ end
113
+
114
+ def to_h
115
+ raise ArgumentError, "Callback required" unless defined?(@success) || defined?(@complete)
116
+
117
+ hash = {}
118
+ hash["parent_bid"] = parent_bid if parent_bid
119
+ hash["description"] = description if description
120
+ hash["success"] = @success if defined?(@success)
121
+ hash["complete"] = @complete if defined?(@complete)
122
+ hash
123
+ end
124
+
125
+ private
126
+
127
+ def to_callback(val)
128
+ case val
129
+ when String
130
+ basic_job.merge({ "jobtype" => val })
131
+ when Class
132
+ basic_job.merge({ "jobtype" => val })
133
+ when Hash
134
+ basic_job.merge(val)
135
+ else
136
+ raise ArgumentError, "Unknown callback #{val}"
137
+ end
138
+ end
139
+
140
+ def basic_job
141
+ {
142
+ "jid" => SecureRandom.hex(12),
143
+ "args" => [],
144
+ "queue" => "default",
145
+ }
146
+ end
147
+ end
148
+
149
+ class BatchStatus
150
+ def initialize(bid)
151
+ @bid = bid
152
+ end
153
+
154
+ def hash
155
+ @hash ||= Faktory.server{|c| c.batch_status(@bid) }
156
+ end
157
+
158
+ def created_at
159
+ hash["created_at"]
160
+ end
161
+
162
+ def description
163
+ hash["description"]
164
+ end
165
+
166
+ def parent_bid
167
+ hash["parent_bid"]
168
+ end
169
+
170
+ def total
171
+ hash["total"]
172
+ end
173
+
174
+ def pending
175
+ hash["pending"]
176
+ end
177
+ end
178
+ end