rabbit_messaging 1.7.0 → 1.8.0

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: efe11548384ee579affeb4b5f73d1bb11381c72537817f91281c535c277ea1ac
4
- data.tar.gz: cd1e1d4afae41948c557df57d9089b2e091b21aaab45d9276329bdfe54b890d9
3
+ metadata.gz: a10737146cf3e6407d500b5cb61af3c6340a435babad47ac7087a5bb966dfd69
4
+ data.tar.gz: '0589fbc1d041763ee953c7a4763814daa66b1f241c8536a2096f43420d2b00e4'
5
5
  SHA512:
6
- metadata.gz: 28dd5ee469eb76e1b072ce812ef8b2e2f184aa8ced27e4b824071c6768c83a328ff472333c17f3221e19b5c7cdf1c29af37a6f0a2042f11011ac4c056e014958
7
- data.tar.gz: 5cd054a92e8942c78f18fdb6c94a36a229e4046669c89c9b26cec17accdc1075dafcd35be1cd741c2849d8750bdec11d067bad4db5004ca73e66bda9d16b55c2
6
+ metadata.gz: 8976861c50915a84af982e2f98d35fd982cce74bd52aa59974bfb213a8dcb65fa10b7b45fee8faf4b13b663ed1b12fb97b23c4d635eb272ddfe8982656da661a
7
+ data.tar.gz: 7db3fad61e5d9caa136a0799d3b96f6785e4b94f68db8fca7d9d1f60862c6e2821f7a0fe2b47ef8b1f650881aae772a17632dcf6635ec728290da8cc27e37670
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.8.0] - 2026-03-25
5
+ ### Added
6
+ - Ability to compress data on publisher level and decompress on consumer
7
+
4
8
  ## [1.7.0] - 2025-08-19
5
9
  ### Added
6
10
  - Ability to specify a custom job class for publishing via `publishing_job_class_callable` config.
data/Gemfile.lock CHANGED
@@ -8,9 +8,11 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- rabbit_messaging (1.7.0)
11
+ rabbit_messaging (1.8.0)
12
12
  bunny (~> 2.0)
13
13
  kicks
14
+ msgpack
15
+ zlib
14
16
 
15
17
  GEM
16
18
  remote: https://rubygems.org/
@@ -66,6 +68,7 @@ GEM
66
68
  logger (1.6.5)
67
69
  method_source (1.1.0)
68
70
  minitest (5.25.4)
71
+ msgpack (1.8.0)
69
72
  parallel (1.26.3)
70
73
  parser (3.3.7.1)
71
74
  ast (~> 2.4.1)
@@ -158,6 +161,7 @@ GEM
158
161
  unicode-display_width (3.1.4)
159
162
  unicode-emoji (~> 4.0, >= 4.0.4)
160
163
  unicode-emoji (4.0.4)
164
+ zlib (3.2.3)
161
165
 
162
166
  PLATFORMS
163
167
  arm64-darwin
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "msgpack"
4
+ require "zlib"
5
+ require "base64"
6
+
7
+ module Rabbit::Compressor
8
+ Error = Class.new(StandardError)
9
+ UncompressingError = Class.new(Error)
10
+
11
+ extend self
12
+
13
+ delegate :decode64, :strict_encode64, to: Base64
14
+
15
+ def dump(data, msgpack_options: {}, with_base64: false)
16
+ dumped = Zlib::Deflate.deflate(MessagePack.pack(data, msgpack_options))
17
+
18
+ return dumped unless with_base64
19
+
20
+ strict_encode64(dumped)
21
+ end
22
+
23
+ def load(data, msgpack_options: {}, with_base64: false)
24
+ return {} unless data
25
+
26
+ data = decode64(data) if with_base64
27
+
28
+ MessagePack.unpack(Zlib::Inflate.inflate(data), msgpack_options)
29
+ rescue Zlib::Error, MessagePack::UnpackError => error
30
+ raise UncompressingError, "Unable to uncompress data, #{error}"
31
+ end
32
+ end
data/lib/rabbit/helper.rb CHANGED
@@ -2,16 +2,22 @@
2
2
 
3
3
  module Rabbit
4
4
  module Helper
5
- def self.generate_message(message_part, parts, index)
5
+ def self.generate_message(message_part, parts, index, compressed: false)
6
6
  if parts == 1
7
- message_part
7
+ format(message_part, compressed)
8
8
  elsif index.zero?
9
- "#{message_part}..."
9
+ "#{format(message_part, compressed)}..."
10
10
  elsif index == parts - 1
11
- "...#{message_part}"
11
+ "...#{format(message_part, compressed)}"
12
12
  else
13
- "...#{message_part}..."
13
+ "...#{format(message_part, compressed)}..."
14
14
  end
15
15
  end
16
+
17
+ def self.format(message_part, compressed)
18
+ return message_part unless compressed
19
+
20
+ "message bytes #{message_part.bytesize}"
21
+ end
16
22
  end
17
23
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Rabbit::Publishing
4
4
  class Message
5
- attr_accessor :routing_key, :event, :data,
5
+ attr_accessor :routing_key, :event, :data, :compress,
6
6
  :confirm_select, :realtime, :headers, :message_id
7
7
  attr_reader :exchange_name
8
8
 
@@ -27,14 +27,16 @@ module Rabbit::Publishing
27
27
  self.realtime = realtime
28
28
  self.headers = headers
29
29
  self.message_id = message_id
30
+ self.compress = headers.with_indifferent_access.fetch(:compress, false)
30
31
  end
31
32
 
32
33
  def to_hash
33
34
  instance_variables.each_with_object({}) do |var, hash|
34
35
  key = var.to_s.delete("@").to_sym
36
+ next if key == :compress
35
37
  value = instance_variable_get(var)
36
38
  hash[key] = value
37
- end.merge(data: JSON.parse(data.to_json))
39
+ end.merge(data: data_for_hash)
38
40
  end
39
41
 
40
42
  def to_s
@@ -55,9 +57,11 @@ module Rabbit::Publishing
55
57
  app_id: Rabbit.config.app_name,
56
58
  headers: headers,
57
59
  message_id: message_id,
58
- }
60
+ }.tap do |ops|
61
+ ops[:content_encoding] = "gzip" if compress
62
+ end
59
63
 
60
- [JSON.dump(data), real_exchange_name, routing_key.to_s, options]
64
+ [dumped_data, real_exchange_name, routing_key.to_s, options]
61
65
  end
62
66
 
63
67
  def exchange_name=(names)
@@ -67,5 +71,22 @@ module Rabbit::Publishing
67
71
  def real_exchange_name
68
72
  [Rabbit.config.group_id, Rabbit.config.project_id, *exchange_name].join(".")
69
73
  end
74
+
75
+ def dumped_data
76
+ return JSON.dump(data) unless compress
77
+ # NOTE: when compress true and realtime false it means data from job
78
+ # already has been compressed and encoded in base64
79
+ return Rabbit::Compressor.dump(data) if realtime
80
+
81
+ Rabbit::Compressor.decode64(data)
82
+ end
83
+
84
+ private
85
+
86
+ def data_for_hash
87
+ return JSON.parse(data.to_json) unless compress
88
+
89
+ Rabbit::Compressor.dump(data, with_base64: true)
90
+ end
70
91
  end
71
92
  end
@@ -66,17 +66,35 @@ module Rabbit
66
66
  message.event, message.confirm_select? ? "confirm" : "no-confirm"
67
67
  ]
68
68
 
69
- message_parts = JSON.dump(message.data)
70
- .scan(/.{1,#{Rabbit.config.logger_message_size_limit}}/)
69
+ return log_compressed(message.dumped_data, metadata: metadata) if message.compress
71
70
 
72
- message_parts.each_with_index do |message_part, index|
73
- message = Rabbit::Helper.generate_message(message_part, message_parts.size, index)
74
- @logger.debug "#{metadata.join ' / '}: #{message}"
75
- end
71
+ log_by_parts(message, metadata: metadata)
76
72
  end
77
73
 
78
74
  def reinitialize_channels_pool
79
75
  MUTEX.synchronize { @pool = ChannelsPool.new(create_client) }
80
76
  end
77
+
78
+ def log_compressed(message_for_publish, metadata:)
79
+ formatted_message = Rabbit::Helper.generate_message(
80
+ message_for_publish, 1, 0, compressed: true
81
+ )
82
+
83
+ @logger.debug "#{metadata.join ' / '}: #{formatted_message}"
84
+ end
85
+
86
+ def log_by_parts(message_for_publish, metadata:)
87
+ message_parts =
88
+ message_for_publish
89
+ .dumped_data
90
+ .scan(/.{1,#{Rabbit.config.logger_message_size_limit}}/)
91
+
92
+ message_parts.each_with_index do |message_part, index|
93
+ formatted_message = Rabbit::Helper.generate_message(
94
+ message_part, message_parts.size, index
95
+ )
96
+ @logger.debug "#{metadata.join ' / '}: #{formatted_message}"
97
+ end
98
+ end
81
99
  end
82
100
  end
@@ -4,7 +4,7 @@ require "rabbit/receiving/malformed_message"
4
4
 
5
5
  module Rabbit::Receiving
6
6
  class Message
7
- attr_accessor :group_id, :project_id, :message_id,
7
+ attr_accessor :group_id, :project_id, :message_id, :compress,
8
8
  :event, :arguments, :original_message
9
9
  attr_reader :data
10
10
 
@@ -15,6 +15,7 @@ module Rabbit::Receiving
15
15
  group_id: group_id,
16
16
  project_id: project_id,
17
17
  event: arguments.fetch(:type),
18
+ compress: arguments.dig(:headers, "compress") || false,
18
19
  data: message,
19
20
  message_id: arguments.fetch(:message_id, nil),
20
21
  arguments: arguments,
@@ -28,12 +29,14 @@ module Rabbit::Receiving
28
29
  event: nil,
29
30
  data: nil,
30
31
  arguments: nil,
31
- original_message: nil
32
+ original_message: nil,
33
+ compress: false
32
34
  )
33
35
  self.group_id = group_id
34
36
  self.project_id = project_id
35
37
  self.message_id = message_id
36
38
  self.event = event
39
+ self.compress = compress
37
40
  self.data = data unless data.nil?
38
41
  self.arguments = arguments
39
42
  self.original_message = original_message
@@ -41,7 +44,7 @@ module Rabbit::Receiving
41
44
 
42
45
  def data=(value)
43
46
  self.original_message = value
44
- parsed = JSON.parse(value).deep_symbolize_keys
47
+ parsed = parsed_data(value)
45
48
  @data = parsed
46
49
  rescue JSON::ParserError => error
47
50
  mark_as_malformed!("JSON::ParserError: #{error.message}")
@@ -60,7 +63,16 @@ module Rabbit::Receiving
60
63
  data: data,
61
64
  arguments: arguments,
62
65
  original_message: original_message,
66
+ compress: compress,
63
67
  }
64
68
  end
69
+
70
+ private
71
+
72
+ def parsed_data(value)
73
+ return JSON.parse(value).deep_symbolize_keys unless compress
74
+
75
+ Rabbit::Compressor.load(value, msgpack_options: { symbolize_keys: true }, with_base64: true)
76
+ end
65
77
  end
66
78
  end
@@ -4,6 +4,7 @@ require "sneakers"
4
4
 
5
5
  require "rabbit"
6
6
  require "rabbit/receiving/receive"
7
+ require "base64"
7
8
 
8
9
  class Rabbit::Receiving::Worker
9
10
  include Sneakers::Worker
@@ -29,8 +30,10 @@ class Rabbit::Receiving::Worker
29
30
  end
30
31
 
31
32
  def receive_message(message, delivery_info, arguments)
33
+ compress = arguments.dig(:headers, "compress") || false
34
+
32
35
  Rabbit::Receiving::Receive.new(
33
- message: message.dup.force_encoding("UTF-8"),
36
+ message: prepare_message_for_receiving(message.dup, compress),
34
37
  delivery_info: delivery_info,
35
38
  arguments: arguments,
36
39
  ).call
@@ -49,4 +52,12 @@ class Rabbit::Receiving::Worker
49
52
  @queue.instance_variable_set(:@banny, nil)
50
53
  run
51
54
  end
55
+
56
+ private
57
+
58
+ def prepare_message_for_receiving(message, compress)
59
+ return Base64.strict_encode64(message.b) if compress
60
+
61
+ message.force_encoding("UTF-8")
62
+ end
52
63
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rabbit
4
- VERSION = "1.7.0"
4
+ VERSION = "1.8.0"
5
5
  end
data/lib/rabbit.rb CHANGED
@@ -4,6 +4,7 @@ require "rabbit/version"
4
4
  require "rabbit/daemon"
5
5
  require "rabbit/publishing"
6
6
  require "rabbit/event_handler"
7
+ require "rabbit/compressor"
7
8
 
8
9
  require "rabbit/extensions/bunny/channel"
9
10
 
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_dependency "bunny", "~> 2.0"
23
23
  spec.add_dependency "kicks"
24
+ spec.add_dependency "msgpack"
25
+ spec.add_dependency "zlib"
24
26
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rabbit_messaging
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Umbrellio
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-09-10 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bunny
@@ -38,6 +37,34 @@ dependencies:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
39
  version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: msgpack
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: zlib
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
41
68
  description: Rabbit (Rabbit Messaging)
42
69
  email:
43
70
  - oss@umbrellio.biz
@@ -60,6 +87,7 @@ files:
60
87
  - config/sneakers.yml
61
88
  - environments/development.rb
62
89
  - lib/rabbit.rb
90
+ - lib/rabbit/compressor.rb
63
91
  - lib/rabbit/daemon.rb
64
92
  - lib/rabbit/event_handler.rb
65
93
  - lib/rabbit/extensions/bunny/channel.rb
@@ -84,7 +112,6 @@ files:
84
112
  homepage: https://github.com/umbrellio/rabbit_messaging
85
113
  licenses: []
86
114
  metadata: {}
87
- post_install_message:
88
115
  rdoc_options: []
89
116
  require_paths:
90
117
  - lib
@@ -99,8 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
126
  - !ruby/object:Gem::Version
100
127
  version: '0'
101
128
  requirements: []
102
- rubygems_version: 3.5.3
103
- signing_key:
129
+ rubygems_version: 3.6.9
104
130
  specification_version: 4
105
131
  summary: Rabbit (Rabbit Messaging)
106
132
  test_files: []