faktory_worker_ruby 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52c0a1a508d1d2451f4c350b71f0d4091e7c134b8c4b57b802023e0f1527bd1d
4
- data.tar.gz: 98fedca04b49b7ab68d8ce398099cfeb92b74d4bd4d3b8951c4f2a15d8d27d10
3
+ metadata.gz: 7739220174ff556abdf6a357cbcd260b6290c732628b27c8dc01ad00be727dd9
4
+ data.tar.gz: 3c87db6e71078419a761c6b34dbdcdd3914d5551f4b42f04140a1621c6568b50
5
5
  SHA512:
6
- metadata.gz: e3a1766171e19dd6750a558dd93eb4734529412674aac18f18b792c716643d5d09e668f0e5ddaf5b291a0c861729a9a29a7918db6b56ac314bbd6d761ab31b6f
7
- data.tar.gz: 5c1f3c6d16d42ecb2e90e82ff926d147526ce483cc5b4ac178459935e4b22c6bf4e9816038f82fa317871c53df54ee631a817ebbfc47c42f85a519e12cccee55
6
+ metadata.gz: b2fc14441abfab58c7cde5401e42adcfe3bb558cd5d5dbf8f6a5db6b176cf2b1d9057370dd0b1daf3d3ca629bb829495bc53167e56e02f0543ec4f89556792ba
7
+ data.tar.gz: 12b5d2fc13701e3c221b9ef8301bdb5b43806b1058336298393b66fc3f8020eb01d9569a43884a9f789a5df754bd24e987a340a74f12f055ae71a244d0d0763d
data/Changes.md CHANGED
@@ -1,5 +1,10 @@
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
+
3
8
  ## 1.0.0
4
9
 
5
10
  - Ruby 2.5+ is now required
data/Gemfile.lock CHANGED
@@ -1,48 +1,51 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- faktory_worker_ruby (1.0.0)
4
+ faktory_worker_ruby (1.0.1)
5
5
  connection_pool (~> 2.2, >= 2.2.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activejob (5.2.2)
11
- activesupport (= 5.2.2)
10
+ activejob (6.0.3.2)
11
+ activesupport (= 6.0.3.2)
12
12
  globalid (>= 0.3.6)
13
- activesupport (5.2.2)
13
+ activesupport (6.0.3.2)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 0.7, < 2)
16
16
  minitest (~> 5.1)
17
17
  tzinfo (~> 1.1)
18
- concurrent-ruby (1.1.4)
19
- connection_pool (2.2.2)
20
- docile (1.3.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)
21
22
  globalid (0.4.2)
22
23
  activesupport (>= 4.2.0)
23
- i18n (1.5.3)
24
+ i18n (1.8.5)
24
25
  concurrent-ruby (~> 1.0)
25
- json (2.1.0)
26
- minitest (5.11.3)
26
+ minitest (5.14.1)
27
27
  minitest-hooks (1.5.0)
28
28
  minitest (> 5.3)
29
- rake (12.3.1)
30
- simplecov (0.16.1)
29
+ rake (13.0.1)
30
+ simplecov (0.18.5)
31
31
  docile (~> 1.1)
32
- json (>= 1.8, < 3)
33
- simplecov-html (~> 0.10.0)
34
- simplecov-html (0.10.2)
32
+ simplecov-html (~> 0.11)
33
+ simplecov-html (0.12.2)
35
34
  thread_safe (0.3.6)
36
- tzinfo (1.2.5)
35
+ tzinfo (1.2.7)
37
36
  thread_safe (~> 0.1)
37
+ zeitwerk (2.4.0)
38
38
 
39
39
  PLATFORMS
40
40
  ruby
41
41
 
42
42
  DEPENDENCIES
43
- activejob (>= 5.1.5)
43
+ activejob (>= 5.2.0)
44
44
  faktory_worker_ruby!
45
45
  minitest (~> 5)
46
46
  minitest-hooks
47
- rake (~> 12)
47
+ rake
48
48
  simplecov
49
+
50
+ BUNDLED WITH
51
+ 2.1.4
data/README.md CHANGED
@@ -34,8 +34,10 @@ server part is [here](https://github.com/contribsys/faktory/)
34
34
 
35
35
  ## Requirements
36
36
 
37
- * Ruby 2.3 or higher
38
- * Faktory 0.9 or higher [Installation](https://github.com/contribsys/faktory/wiki/Installation)
37
+ * Ruby 2.5 or higher
38
+ * Faktory 1.2 or higher [Installation](https://github.com/contribsys/faktory/wiki/Installation)
39
+
40
+ Optionally, Rails 5.2+ for ActiveJob.
39
41
 
40
42
  ## Installation
41
43
 
@@ -95,4 +97,4 @@ PRs to improve this are very welcome).
95
97
 
96
98
  ## Author
97
99
 
98
- Mike Perham, @mperham, mike @ contribsys.com
100
+ Mike Perham, @getajobmike, mike @ contribsys.com
@@ -17,8 +17,8 @@ Gem::Specification.new do |gem|
17
17
  gem.required_ruby_version = ">= 2.5.0"
18
18
 
19
19
  gem.add_dependency 'connection_pool', '~> 2.2', ">= 2.2.2"
20
- gem.add_development_dependency 'activejob', '>= 5.1.5'
20
+ gem.add_development_dependency 'activejob', '>= 5.2.0'
21
21
  gem.add_development_dependency 'minitest', '~> 5'
22
22
  gem.add_development_dependency 'minitest-hooks'
23
- gem.add_development_dependency 'rake', '~> 12'
23
+ gem.add_development_dependency 'rake'
24
24
  end
@@ -32,8 +32,12 @@ module ActiveJob
32
32
  hash["retry"] = opts.delete("retry") if opts.has_key?("retry")
33
33
  hash["custom"] = opts.merge(hash["custom"])
34
34
  end
35
- # Faktory::Client does not support symbols as keys
36
- Faktory::Client.new.push(hash)
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
37
41
  end
38
42
 
39
43
  class JobWrapper #:nodoc:
@@ -3,6 +3,8 @@ require 'json'
3
3
  require 'uri'
4
4
  require 'digest'
5
5
  require 'securerandom'
6
+ require 'timeout'
7
+ require 'faktory/io'
6
8
 
7
9
  module Faktory
8
10
  class BaseError < StandardError; end
@@ -15,6 +17,9 @@ module Faktory
15
17
  # Most APIs will return `true` if the operation succeeded or raise a
16
18
  # Faktory::BaseError if there was an unexpected error.
17
19
  class Client
20
+ # provides gets() and read() that respect a read timeout
21
+ include Faktory::ReadTimeout
22
+
18
23
  @@random_process_wid = ""
19
24
 
20
25
  DEFAULT_TIMEOUT = 5.0
@@ -45,6 +50,7 @@ module Faktory
45
50
  #
46
51
  # Note above, the URL can contain the password for secure installations.
47
52
  def initialize(url: uri_from_env || 'tcp://localhost:7419', debug: false, timeout: DEFAULT_TIMEOUT)
53
+ super
48
54
  @debug = debug
49
55
  @location = URI(url)
50
56
  @timeout = timeout
@@ -220,19 +226,13 @@ module Faktory
220
226
  end
221
227
 
222
228
  def open(timeout = DEFAULT_TIMEOUT)
223
- # this is the read/write timeout, not open.
224
- secs = Integer(timeout)
225
- usecs = Integer((timeout - secs) * 1_000_000)
226
- optval = [secs, usecs].pack("l_2")
227
229
  if tls?
228
230
  sock = TCPSocket.new(@location.hostname, @location.port)
229
231
  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
230
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval)
231
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval)
232
232
 
233
233
  ctx = OpenSSL::SSL::SSLContext.new
234
234
  ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_PEER)
235
- ctx.ssl_version = :TLSv1_2
235
+ ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION
236
236
 
237
237
  @sock = OpenSSL::SSL::SSLSocket.new(sock, ctx).tap do |socket|
238
238
  socket.sync_close = true
@@ -241,8 +241,6 @@ module Faktory
241
241
  else
242
242
  @sock = TCPSocket.new(@location.hostname, @location.port)
243
243
  @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
244
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval)
245
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval)
246
244
  end
247
245
 
248
246
  payload = {
@@ -297,9 +295,12 @@ module Faktory
297
295
 
298
296
  begin
299
297
  yield
300
- rescue Errno::EPIPE, Errno::ECONNRESET
298
+ rescue SystemCallError, SocketError, TimeoutError
301
299
  if retryable
302
300
  retryable = false
301
+
302
+ @sock.close rescue nil
303
+ @sock = nil
303
304
  open(@timeout)
304
305
  retry
305
306
  else
@@ -311,7 +312,7 @@ module Faktory
311
312
  # I love pragmatic, simple protocols. Thanks antirez!
312
313
  # https://redis.io/topics/protocol
313
314
  def result
314
- line = @sock.gets
315
+ line = gets
315
316
  debug "< #{line}" if @debug
316
317
  raise Errno::ECONNRESET, "No response" unless line
317
318
  chr = line[0]
@@ -320,8 +321,8 @@ module Faktory
320
321
  elsif chr == '$'
321
322
  count = line[1..-1].strip.to_i
322
323
  return nil if count == -1
323
- data = @sock.read(count) if count > 0
324
- line = @sock.gets # read extra linefeeds
324
+ data = read(count) if count > 0
325
+ line = gets # read extra linefeeds
325
326
  data
326
327
  elsif chr == '-'
327
328
  # Server can respond with:
@@ -7,7 +7,7 @@ module Faktory
7
7
  def create(options={})
8
8
  size = Faktory.worker? ? (Faktory.options[:concurrency] + 2) : 5
9
9
  ConnectionPool.new(:timeout => options[:pool_timeout] || 1, :size => size) do
10
- Faktory::Client.new(options)
10
+ Faktory::Client.new(**options)
11
11
  end
12
12
  end
13
13
  end
data/lib/faktory/io.rb ADDED
@@ -0,0 +1,51 @@
1
+ require "io/wait"
2
+
3
+ # this is the necessary magic to get a line-oriented protocol to
4
+ # respect a read timeout. unfortunately Ruby sockets do not provide any
5
+ # timeout support directly, delegating that to the IO reactor.
6
+ module Faktory
7
+ class TimeoutError < Timeout::Error; end
8
+
9
+ module ReadTimeout
10
+ CRLF = "\r\n"
11
+ BUFSIZE = 16_384
12
+
13
+ # Ruby's TCP sockets do not implement timeouts.
14
+ # We have to implement them ourselves by using
15
+ # nonblocking IO and IO.select.
16
+ def initialize(**opts)
17
+ @buf = "".dup
18
+ @timeout = opts[:timeout] || 5
19
+ end
20
+
21
+ def gets
22
+ while (crlf = @buf.index(CRLF)).nil?
23
+ @buf << read_timeout(BUFSIZE)
24
+ end
25
+
26
+ @buf.slice!(0, crlf + 2)
27
+ end
28
+
29
+ def read(nbytes)
30
+ result = @buf.slice!(0, nbytes)
31
+ result << read_timeout(nbytes - result.bytesize) while result.bytesize < nbytes
32
+ result
33
+ end
34
+
35
+ private
36
+ def read_timeout(nbytes)
37
+ loop do
38
+ result = @sock.read_nonblock(nbytes, exception: false)
39
+ if result == :wait_readable
40
+ raise Faktory::TimeoutError unless @sock.wait_readable(@timeout)
41
+ elsif result == :wait_writable
42
+ raise Faktory::TimeoutError unless @sock.wait_writeable(@timeout)
43
+ elsif result == nil
44
+ raise Errno::ECONNRESET
45
+ else
46
+ return result
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/faktory/rails.rb CHANGED
@@ -23,9 +23,19 @@ module Faktory
23
23
  if ::Rails::VERSION::MAJOR < 5
24
24
  raise "Your current version of Rails, #{::Rails::VERSION::STRING}, is not supported"
25
25
  end
26
-
26
+
27
27
  Faktory.options[:reloader] = Faktory::Rails::Reloader.new
28
28
  end
29
+
30
+ begin
31
+ # https://github.com/rails/rails/pull/41248
32
+ if defined?(::Mail::SMTP)
33
+ ::Mail::SMTP::DEFAULTS[:read_timeout] ||= 5
34
+ ::Mail::SMTP::DEFAULTS[:open_timeout] ||= 5
35
+ end
36
+ rescue => ex
37
+ # ignore
38
+ end
29
39
  end
30
40
 
31
41
  class Reloader
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Faktory
3
- VERSION = "1.0.0"
3
+ VERSION = "1.0.1"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faktory_worker_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-28 00:00:00.000000000 Z
11
+ date: 2021-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: 5.1.5
39
+ version: 5.2.0
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 5.1.5
46
+ version: 5.2.0
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: minitest
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -76,16 +76,16 @@ dependencies:
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
79
+ - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '12'
81
+ version: '0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - "~>"
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '12'
88
+ version: '0'
89
89
  description: Ruby worker for Faktory.
90
90
  email:
91
91
  - mike@contribsys.com
@@ -112,6 +112,7 @@ files:
112
112
  - lib/faktory/connection.rb
113
113
  - lib/faktory/exception_handler.rb
114
114
  - lib/faktory/fetch.rb
115
+ - lib/faktory/io.rb
115
116
  - lib/faktory/job.rb
116
117
  - lib/faktory/job_logger.rb
117
118
  - lib/faktory/launcher.rb
@@ -132,7 +133,7 @@ homepage: https://github.com/contribsys/faktory_worker_ruby
132
133
  licenses:
133
134
  - LGPL-3.0
134
135
  metadata: {}
135
- post_install_message:
136
+ post_install_message:
136
137
  rdoc_options: []
137
138
  require_paths:
138
139
  - lib
@@ -147,8 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
148
  - !ruby/object:Gem::Version
148
149
  version: '0'
149
150
  requirements: []
150
- rubygems_version: 3.0.3
151
- signing_key:
151
+ rubygems_version: 3.2.6
152
+ signing_key:
152
153
  specification_version: 4
153
154
  summary: Ruby worker for Faktory
154
155
  test_files: []