beetle 3.5.4 → 3.5.6

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: 38849c0467ba80b057fa8bc659ad98b025dd1c6d9ce416a4f2c48dff91f50fac
4
- data.tar.gz: 791b45e82bcddf8bca2923db816475aa16bb81efa96d7c38381de12ea18fe65b
3
+ metadata.gz: 05c783e8ae2cd39837e587954e252f6f8cd772756536cb51de030fdebddfa808
4
+ data.tar.gz: 63403a3e7c70a2840daedfbb41f067c260ac6ae0b34920334f0e26bb999b936b
5
5
  SHA512:
6
- metadata.gz: cbd464c6759316b86ab5732029fefa39518360dc40f055e729d585b9304ad84c9597c7e37908826bfc0347c109c89e7729db8096b2bf51ec64c536c272c9b6b3
7
- data.tar.gz: c7ef92729c7d9cf38c7ec5e0a90fff5147fb4350d568c82c93e58c76b5c358d74929517b888bb8f96386230f0b2f50272488981668d183294fbda5ac86893ade
6
+ metadata.gz: c43c533f5946971f25cbc664809842498f0e52b0404e0a23b772940707adf53288be74d7ca1f8f3cae1943a1d311a19f15b2fc4e3458b6347597367002e65af0
7
+ data.tar.gz: ae915f36ce7d9e78a10421b17bca59710b87964b3904db14ea1064dc6d87147d3e9c2faf6b552982d73ed227e88b4bd8b2d06d4a9d8335654d6008c95eade00b
data/beetle.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.specification_version = 3
26
26
  s.add_runtime_dependency "bunny", "~> 0.7.12"
27
- s.add_runtime_dependency "redis", [">= 4.2.1", "< 5.0"]
27
+ s.add_runtime_dependency "redis", ">= 4.2.1"
28
28
  s.add_runtime_dependency "hiredis", ">= 0.4.5"
29
29
  s.add_runtime_dependency "amq-protocol", "= 2.3.2"
30
30
  s.add_runtime_dependency "amqp", "= 1.8.0"
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
36
36
  s.add_development_dependency "daemons", ">= 1.2.0"
37
37
  s.add_development_dependency "i18n"
38
38
  s.add_development_dependency "minitest", "~> 5.1"
39
+ s.add_development_dependency "minitest-reporters"
39
40
  s.add_development_dependency "mocha", "~> 1.14"
40
41
  s.add_development_dependency "mysql2", "~> 0.5"
41
42
  s.add_development_dependency "rake", "~> 13.0"
@@ -46,4 +47,5 @@ Gem::Specification.new do |s|
46
47
  s.add_development_dependency 'redcarpet'
47
48
  s.add_development_dependency 'github-markup'
48
49
  s.add_development_dependency 'byebug'
50
+ s.add_development_dependency 'appraisal'
49
51
  end
@@ -46,7 +46,7 @@ end
46
46
 
47
47
  def system_notification_log_path
48
48
  log_path = tmp_path + "/system_notifications.log"
49
- `touch #{log_path}` unless File.exists?(log_path)
49
+ `touch #{log_path}` unless File.exist?(log_path)
50
50
  log_path
51
51
  end
52
52
 
@@ -131,11 +131,11 @@ module TestDaemons
131
131
  private
132
132
 
133
133
  def create_dir
134
- FileUtils.mkdir(dir) unless File.exists?(dir)
134
+ FileUtils.mkdir(dir) unless File.exist?(dir)
135
135
  end
136
136
 
137
137
  def remove_dir
138
- FileUtils.rm_r(dir) if File.exists?(dir)
138
+ FileUtils.rm_r(dir) if File.exist?(dir)
139
139
  end
140
140
 
141
141
  def create_config
@@ -145,11 +145,11 @@ module TestDaemons
145
145
  end
146
146
 
147
147
  def remove_config
148
- FileUtils.rm(config_filename) if File.exists?(config_filename)
148
+ FileUtils.rm(config_filename) if File.exist?(config_filename)
149
149
  end
150
150
 
151
151
  def remove_pid_file
152
- FileUtils.rm(pid_file) if File.exists?(pid_file)
152
+ FileUtils.rm(pid_file) if File.exist?(pid_file)
153
153
  end
154
154
 
155
155
  def tmp_path
@@ -33,6 +33,12 @@ module Beetle
33
33
  attr_accessor :redis_servers
34
34
  # redis database number to use for the message deduplication store (defaults to <tt>4</tt>)
35
35
  attr_accessor :redis_db
36
+ # redis connect timeout. defaults to 5 seconds.
37
+ attr_accessor :redis_connect_timeout
38
+ # redis read timeout. defaults to 5 seconds.
39
+ attr_accessor :redis_read_timeout
40
+ # redis write timeout. defaults to 5 seconds.
41
+ attr_accessor :redis_write_timeout
36
42
 
37
43
  # how long we should repeatedly retry a redis operation before giving up, with a one
38
44
  # second sleep between retries (defaults to <tt>180.seconds</tt>). this value needs to be
@@ -157,6 +163,9 @@ module Beetle
157
163
  self.redis_server = "localhost:6379"
158
164
  self.redis_servers = ""
159
165
  self.redis_db = 4
166
+ self.redis_connect_timeout = 5.0
167
+ self.redis_read_timeout = 5.0
168
+ self.redis_write_timeout = 5.0
160
169
  self.redis_failover_timeout = 180.seconds
161
170
  self.redis_status_key_expiry_interval = 0.seconds
162
171
  self.redis_failover_client_heartbeat_interval = 10.seconds
@@ -217,6 +226,17 @@ module Beetle
217
226
  end
218
227
  end
219
228
 
229
+ # redis optins to be passed to Redis.new
230
+ def redis_options
231
+ {
232
+ db: redis_db,
233
+ connect_timeout: redis_connect_timeout,
234
+ read_timeout: redis_read_timeout,
235
+ write_timeout: redis_write_timeout,
236
+ logger: redis_logger,
237
+ }
238
+ end
239
+
220
240
  private
221
241
  def load_config
222
242
  raw = ERB.new(IO.read(config_file)).result
@@ -62,7 +62,7 @@ module Beetle
62
62
  # store completion status for given <tt>msg_id</tt> if it doesn't exist yet. Returns whether the
63
63
  # operation was successful.
64
64
  def setnx_completed!(msg_id)
65
- expiry = @config.redis_status_key_expiry_interval
65
+ expiry = @config.redis_status_key_expiry_interval.to_i
66
66
  return true if expiry == 0
67
67
  with_failover do
68
68
  redis.set(
@@ -109,7 +109,7 @@ module Beetle
109
109
 
110
110
  # delete all keys associated with the given <tt>msg_id</tt>.
111
111
  def del_keys(msg_id)
112
- expiry = @config.redis_status_key_expiry_interval
112
+ expiry = @config.redis_status_key_expiry_interval.to_i
113
113
  keys = keys(msg_id)
114
114
  status_key = keys.shift if expiry > 0
115
115
  with_failover do
@@ -150,7 +150,7 @@ module Beetle
150
150
 
151
151
  # set current redis master instance (as specified in the Beetle::Configuration)
152
152
  def redis_master_from_server_string
153
- @current_master ||= Redis.from_server_string(@config.redis_server, :db => @config.redis_db, :logger => @config.redis_logger)
153
+ @current_master ||= Redis.from_server_string(@config.redis_server, @config.redis_options)
154
154
  end
155
155
 
156
156
  # set current redis master from master file
@@ -168,7 +168,7 @@ module Beetle
168
168
  def set_current_redis_master_from_master_file
169
169
  @last_time_master_file_changed = File.mtime(@config.redis_server)
170
170
  server_string = extract_redis_master(read_master_file)
171
- @current_master = !server_string.blank? ? Redis.from_server_string(server_string, :db => @config.redis_db, :logger => @config.redis_logger) : nil
171
+ @current_master = !server_string.blank? ? Redis.from_server_string(server_string, @config.redis_options ) : nil
172
172
  end
173
173
 
174
174
  # extract redis master from file content and return the server for our system
@@ -72,15 +72,15 @@ module Beetle
72
72
 
73
73
  def setup(opts) #:nodoc:
74
74
  @server = opts[:server]
75
- @timeout = opts[:timeout] || DEFAULT_HANDLER_TIMEOUT
76
- @delay = opts[:delay] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY
75
+ @timeout = opts[:timeout] || DEFAULT_HANDLER_TIMEOUT.to_i
76
+ @delay = (opts[:delay] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS_DELAY).ceil
77
77
  @attempts_limit = opts[:attempts] || DEFAULT_HANDLER_EXECUTION_ATTEMPTS
78
78
  @exceptions_limit = opts[:exceptions] || DEFAULT_EXCEPTION_LIMIT
79
79
  @attempts_limit = @exceptions_limit + 1 if @attempts_limit <= @exceptions_limit
80
80
  @retry_on = opts[:retry_on] || nil
81
81
  @store = opts[:store]
82
82
  max_delay = opts[:max_delay] || @delay
83
- @max_delay = max_delay if max_delay >= 2*@delay
83
+ @max_delay = max_delay.ceil if max_delay >= 2*@delay
84
84
  end
85
85
 
86
86
  # extracts various values from the AMQP header properties
@@ -101,7 +101,7 @@ module Beetle
101
101
  def self.publishing_options(opts = {}) #:nodoc:
102
102
  flags = 0
103
103
  flags |= FLAG_REDUNDANT if opts[:redundant]
104
- expires_at = now + (opts[:ttl] || DEFAULT_TTL)
104
+ expires_at = now + (opts[:ttl] || DEFAULT_TTL).to_i
105
105
  opts = opts.slice(*PUBLISHING_KEYS)
106
106
  opts[:message_id] = generate_uuid.to_s
107
107
  opts[:timestamp] = now
@@ -165,7 +165,7 @@ module Beetle
165
165
 
166
166
  # store handler timeout timestamp in the deduplication store
167
167
  def set_timeout!
168
- @store.set(msg_id, :timeout, now + timeout)
168
+ @store.set(msg_id, :timeout, (now + timeout).ceil)
169
169
  end
170
170
 
171
171
  # handler timed out?
@@ -230,7 +230,7 @@ module Beetle
230
230
  # have we already seen this message? if not, set the status to "incomplete" and store
231
231
  # the message exipration timestamp in the deduplication store.
232
232
  def key_exists?
233
- old_message = !@store.msetnx(msg_id, :status =>"incomplete", :expires => @expires_at, :timeout => now + timeout)
233
+ old_message = !@store.msetnx(msg_id, :status =>"incomplete", :expires => @expires_at.to_i, :timeout => (now + timeout).to_i)
234
234
  if old_message
235
235
  logger.debug "Beetle: received duplicate message: #{msg_id} on queue: #{@queue}"
236
236
  end
@@ -3,6 +3,7 @@ class Redis #:nodoc:
3
3
  def self.from_server_string(server_string, options = {})
4
4
  host, port = server_string.split(':')
5
5
  options = {:host => host, :port => port}.update(options)
6
+ options.delete(:logger) if Redis::VERSION >= "5.0"
6
7
  new(options)
7
8
  end
8
9
 
@@ -79,6 +80,19 @@ class Redis #:nodoc:
79
80
  super != 0
80
81
  end
81
82
 
83
+ elsif Redis::VERSION >= "5.0.0"
84
+
85
+ # redis 5.0.0 has a shutdown method which raises if a connection to the redis server
86
+ # cannot be established.
87
+ module SaneShutdown
88
+ def shutdown
89
+ super
90
+ rescue RedisClient::CannotConnectError
91
+ nil
92
+ end
93
+ end
94
+ prepend SaneShutdown
95
+
82
96
  elsif Redis::VERSION >= "4.0.0"
83
97
 
84
98
  # redis 4.0.0 has a shutdown method which raises if a connection to the redis server
@@ -1,3 +1,3 @@
1
1
  module Beetle
2
- VERSION = "3.5.4"
2
+ VERSION = "3.5.6"
3
3
  end
data/lib/beetle.rb CHANGED
@@ -1,8 +1,19 @@
1
1
  $:.unshift(File.expand_path('..', __FILE__))
2
2
  require 'bunny' # which bunny picks up
3
3
  require 'qrack/errors' # needed by the publisher
4
- require 'redis/connection/hiredis' # require *before* redis as specified in the redis-rb gem docs
5
- require 'redis'
4
+
5
+ if Gem::Version.new(Bunny::VERSION) <= Gem::Version.new("0.7.12") && !defined?(::Fixnum)
6
+ require 'qrack/transport/buffer09'
7
+ Qrack::Transport09::Buffer.class_eval "Fixnum = Integer"
8
+ end
9
+
10
+ begin
11
+ require 'redis/connection/hiredis' # require *before* redis as specified in the redis-rb gem docs
12
+ require 'redis'
13
+ rescue LoadError
14
+ require 'redis'
15
+ require 'hiredis-client'
16
+ end
6
17
  require 'active_support/all'
7
18
  require 'set'
8
19
  require 'socket'
@@ -0,0 +1,32 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class BunnyBehaviorTest < Minitest::Test
4
+ test "publishing fixnums and hashes works in amqp headers" do
5
+ client = Beetle::Client.new
6
+ client.register_queue(:test)
7
+ client.register_message(:test)
8
+
9
+ # purge the test queue
10
+ client.purge(:test)
11
+
12
+ # empty the dedup store
13
+ client.deduplication_store.flushdb
14
+
15
+ # register our handler to the message, check out the message.rb for more stuff you can get from the message object
16
+ message = nil
17
+ client.register_handler(:test) {|msg| message = msg; client.stop_listening }
18
+
19
+ # publish our message (NOTE: empty message bodies don't work, most likely due to bugs in bunny/amqp)
20
+ published = client.publish(:test, 'bam', headers: { foo: 1, table: {bar: "baz"}})
21
+
22
+ # start listening
23
+ client.listen
24
+ client.stop_publishing
25
+
26
+ assert_equal 1, published
27
+ assert_equal "bam", message.data
28
+ headers = message.header.attributes[:headers]
29
+ assert_equal 1, headers["foo"]
30
+ assert_equal({"bar" => "baz"}, headers["table"])
31
+ end
32
+ end
@@ -57,7 +57,11 @@ module Beetle
57
57
 
58
58
  class HiredisLoadedTest < Minitest::Test
59
59
  test "should be using hiredis instead of the redis ruby backend" do
60
- assert defined?(Hiredis)
60
+ if Redis::VERSION < "5.0"
61
+ assert defined?(Hiredis)
62
+ else
63
+ assert_equal RedisClient.default_driver, RedisClient::HiredisConnection
64
+ end
61
65
  end
62
66
  end
63
67
 
data/test/test_helper.rb CHANGED
@@ -7,9 +7,15 @@ end
7
7
 
8
8
  require 'minitest/autorun'
9
9
  require 'minitest/unit'
10
- require 'minitest/pride' if ENV['RAINBOW_COLORED_TESTS'] == "1" && $stdout.tty?
11
10
  require 'mocha/minitest'
12
11
 
12
+ require 'minitest/reporters'
13
+ if ENV['MINITEST_REPORTER']
14
+ Minitest::Reporters.use!
15
+ else
16
+ Minitest::Reporters.use!([Minitest::Reporters::DefaultReporter.new])
17
+ end
18
+
13
19
  require File.expand_path(File.dirname(__FILE__) + '/../lib/beetle')
14
20
  require 'eventmachine'
15
21
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beetle
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.4
4
+ version: 3.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Kaes
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2022-08-30 00:00:00.000000000 Z
15
+ date: 2023-03-23 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bunny
@@ -35,9 +35,6 @@ dependencies:
35
35
  - - ">="
36
36
  - !ruby/object:Gem::Version
37
37
  version: 4.2.1
38
- - - "<"
39
- - !ruby/object:Gem::Version
40
- version: '5.0'
41
38
  type: :runtime
42
39
  prerelease: false
43
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -45,9 +42,6 @@ dependencies:
45
42
  - - ">="
46
43
  - !ruby/object:Gem::Version
47
44
  version: 4.2.1
48
- - - "<"
49
- - !ruby/object:Gem::Version
50
- version: '5.0'
51
45
  - !ruby/object:Gem::Dependency
52
46
  name: hiredis
53
47
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +182,20 @@ dependencies:
188
182
  - - "~>"
189
183
  - !ruby/object:Gem::Version
190
184
  version: '5.1'
185
+ - !ruby/object:Gem::Dependency
186
+ name: minitest-reporters
187
+ requirement: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ version: '0'
192
+ type: :development
193
+ prerelease: false
194
+ version_requirements: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - ">="
197
+ - !ruby/object:Gem::Version
198
+ version: '0'
191
199
  - !ruby/object:Gem::Dependency
192
200
  name: mocha
193
201
  requirement: !ruby/object:Gem::Requirement
@@ -328,6 +336,20 @@ dependencies:
328
336
  - - ">="
329
337
  - !ruby/object:Gem::Version
330
338
  version: '0'
339
+ - !ruby/object:Gem::Dependency
340
+ name: appraisal
341
+ requirement: !ruby/object:Gem::Requirement
342
+ requirements:
343
+ - - ">="
344
+ - !ruby/object:Gem::Version
345
+ version: '0'
346
+ type: :development
347
+ prerelease: false
348
+ version_requirements: !ruby/object:Gem::Requirement
349
+ requirements:
350
+ - - ">="
351
+ - !ruby/object:Gem::Version
352
+ version: '0'
331
353
  description: A highly available, reliable messaging infrastructure
332
354
  email: opensource@xing.com
333
355
  executables: []
@@ -385,6 +407,7 @@ files:
385
407
  - test/beetle/amqp_gem_behavior_test.rb
386
408
  - test/beetle/base_test.rb
387
409
  - test/beetle/beetle_test.rb
410
+ - test/beetle/bunny_behavior_test.rb
388
411
  - test/beetle/client_test.rb
389
412
  - test/beetle/configuration_test.rb
390
413
  - test/beetle/deduplication_store_test.rb
@@ -418,7 +441,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
418
441
  - !ruby/object:Gem::Version
419
442
  version: 1.3.7
420
443
  requirements: []
421
- rubygems_version: 3.3.19
444
+ rubygems_version: 3.4.6
422
445
  signing_key:
423
446
  specification_version: 3
424
447
  summary: High Availability AMQP Messaging with Redundant Queues
@@ -426,6 +449,7 @@ test_files:
426
449
  - test/beetle/amqp_gem_behavior_test.rb
427
450
  - test/beetle/base_test.rb
428
451
  - test/beetle/beetle_test.rb
452
+ - test/beetle/bunny_behavior_test.rb
429
453
  - test/beetle/client_test.rb
430
454
  - test/beetle/configuration_test.rb
431
455
  - test/beetle/deduplication_store_test.rb