hawkei 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +48 -0
  5. data/.ruby-version +1 -0
  6. data/.tool-versions +1 -0
  7. data/.travis.yml +11 -0
  8. data/Gemfile +12 -0
  9. data/LICENCE +21 -0
  10. data/Makefile +9 -0
  11. data/README.md +17 -0
  12. data/Rakefile +4 -0
  13. data/hawkei.gemspec +28 -0
  14. data/lib/hawkei/api_operation/delete.rb +38 -0
  15. data/lib/hawkei/api_operation/save.rb +57 -0
  16. data/lib/hawkei/api_resource.rb +130 -0
  17. data/lib/hawkei/batch.rb +18 -0
  18. data/lib/hawkei/config.rb +123 -0
  19. data/lib/hawkei/errors.rb +41 -0
  20. data/lib/hawkei/formated_logger.rb +45 -0
  21. data/lib/hawkei/hawkei_object.rb +179 -0
  22. data/lib/hawkei/library_name.rb +3 -0
  23. data/lib/hawkei/message.rb +79 -0
  24. data/lib/hawkei/plugins/rack/middleware.rb +139 -0
  25. data/lib/hawkei/plugins/rails/data.rb +19 -0
  26. data/lib/hawkei/plugins/rails/middleware_data.rb +28 -0
  27. data/lib/hawkei/plugins/rails/railtie.rb +23 -0
  28. data/lib/hawkei/plugins/sidekiq/client_middleware.rb +19 -0
  29. data/lib/hawkei/plugins/sidekiq/load.rb +14 -0
  30. data/lib/hawkei/plugins/sidekiq/server_middleware.rb +48 -0
  31. data/lib/hawkei/plugins.rb +17 -0
  32. data/lib/hawkei/processor/async.rb +50 -0
  33. data/lib/hawkei/processor/batch.rb +84 -0
  34. data/lib/hawkei/processor/worker.rb +113 -0
  35. data/lib/hawkei/request.rb +134 -0
  36. data/lib/hawkei/store.rb +49 -0
  37. data/lib/hawkei/util.rb +180 -0
  38. data/lib/hawkei/version.rb +3 -0
  39. data/lib/hawkei/watcher.rb +15 -0
  40. data/lib/hawkei.rb +170 -0
  41. data/spec/lib/hawkei/api_resource_spec.rb +109 -0
  42. data/spec/lib/hawkei/batch_spec.rb +14 -0
  43. data/spec/lib/hawkei/config_spec.rb +36 -0
  44. data/spec/lib/hawkei/formated_logger_spec.rb +99 -0
  45. data/spec/lib/hawkei/hawkei_object_spec.rb +123 -0
  46. data/spec/lib/hawkei/message_spec.rb +178 -0
  47. data/spec/lib/hawkei/plugins/rack/middleware_spec.rb +88 -0
  48. data/spec/lib/hawkei/plugins/rails/data_spec.rb +22 -0
  49. data/spec/lib/hawkei/plugins/rails/middleware_data_spec.rb +46 -0
  50. data/spec/lib/hawkei/plugins/sidekiq/client_middleware_spec.rb +15 -0
  51. data/spec/lib/hawkei/plugins/sidekiq/server_middleware_spec.rb +58 -0
  52. data/spec/lib/hawkei/processor/async_spec.rb +36 -0
  53. data/spec/lib/hawkei/processor/batch_spec.rb +51 -0
  54. data/spec/lib/hawkei/processor/worker_spec.rb +100 -0
  55. data/spec/lib/hawkei/store_spec.rb +82 -0
  56. data/spec/lib/hawkei/util_spec.rb +132 -0
  57. data/spec/lib/hawkei/watcher_spec.rb +25 -0
  58. data/spec/lib/hawkei_spec.rb +175 -0
  59. data/spec/spec_helper.rb +33 -0
  60. data/spec/support/rack_app.rb +12 -0
  61. metadata +206 -0
@@ -0,0 +1,179 @@
1
+ module Hawkei
2
+ ##
3
+ # == Hawkei \Object
4
+ #
5
+ # Define the API objects
6
+ class HawkeiObject
7
+ ##
8
+ # @return [Hash] JSON parsed response
9
+ attr_reader :raw
10
+
11
+ ##
12
+ # @return [Hash] JSON parsed response
13
+ attr_reader :data
14
+
15
+ attr_reader :errors
16
+
17
+ attr_reader :successful
18
+ alias successful? successful
19
+
20
+ class << self
21
+
22
+ ##
23
+ # Initialize from the API response
24
+ #
25
+ # @return [Hawkei::HawkeiObject]
26
+ def initialize_from(response, object = new)
27
+ object.load_response_api(response.is_a?(Hash) ? response : Util.safe_json_parse(response))
28
+ object.update_attributes(Hawkei::Util.except_keys(object.raw, :data))
29
+ if object.raw[:object] == 'list'
30
+ object.raw[:data].each do |response_object|
31
+ data = object.type_from_string_object(response_object[:object]).initialize_from(response_object)
32
+
33
+ object.add_data(data)
34
+ end
35
+ end
36
+
37
+ object
38
+ end
39
+
40
+ end
41
+
42
+ ##
43
+ # Update the object based on the response from the API
44
+ # Remove and new accessor
45
+ #
46
+ # @param [Hash] response
47
+ #
48
+ # @return [Hawkei::HawkeiObject]
49
+ def update_from(response)
50
+ self.class.initialize_from(response, self)
51
+
52
+ (@values.keys - raw.keys).each { |key| remove_accessor(key) }
53
+
54
+ self
55
+ end
56
+
57
+ ##
58
+ # Initialize and create accessor for values
59
+ #
60
+ # @params [Hash] values
61
+ def initialize(values = {})
62
+ @data = []
63
+ @values = {}
64
+
65
+ update_attributes(values)
66
+ end
67
+
68
+ ##
69
+ # get attribute value
70
+ def [](key)
71
+ @values[key.to_sym]
72
+ end
73
+
74
+ ##
75
+ # set attribute value
76
+ def []=(key, value)
77
+ send(:"#{key}=", value)
78
+ end
79
+
80
+ ##
81
+ # @return [Array] all the keys
82
+ def keys
83
+ @values.keys
84
+ end
85
+
86
+ ##
87
+ # @return [Hash] values to hash
88
+ def to_hash
89
+ @values
90
+ end
91
+
92
+ ##
93
+ # @return [JSON] values to JSON
94
+ def to_json(_object = nil)
95
+ JSON.generate(@values)
96
+ end
97
+
98
+ ##
99
+ # Update the attribute and add accessor for new attributes
100
+ #
101
+ # @param [Hash] values
102
+ def update_attributes(attributes)
103
+ attributes.each do |(key, value)|
104
+ add_accessor(key, value)
105
+ end
106
+ end
107
+
108
+ ##
109
+ # Load the root components for the API response
110
+ #
111
+ # @param [Hash] values
112
+ def load_response_api(response)
113
+ @raw = Hawkei::Util.deep_underscore_key(response)
114
+ @successful = true
115
+ end
116
+
117
+ ##
118
+ # Add data for sub-object
119
+ #
120
+ # @param [Object] data
121
+ def add_data(data)
122
+ @data << data
123
+ end
124
+
125
+ ##
126
+ # Create an object from a string
127
+ #
128
+ # @param [String] object to be build
129
+ #
130
+ # @return [Object]
131
+ def type_from_string_object(string_object)
132
+ klass_name = Hawkei::Util.camelize(string_object.to_s)
133
+
134
+ Object.const_get("Hawkei::#{klass_name}")
135
+ end
136
+
137
+ def inspect
138
+ id_string = respond_to?(:id) && !id.nil? ? " id=#{id}" : ''
139
+ "#<#{self.class}:0x#{object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
140
+ end
141
+
142
+ def method_missing(name, *args)
143
+ super unless name.to_s.end_with?('=')
144
+
145
+ attribute = name.to_s[0...-1].to_sym
146
+ value = args.first
147
+
148
+ add_accessor(attribute, value)
149
+ end
150
+
151
+ private
152
+
153
+ def add_accessors(keys, payload = raw)
154
+ keys.each do |key|
155
+ add_accessor(key, payload[key])
156
+ end
157
+ end
158
+
159
+ def add_accessor(name, value)
160
+ @values[name] = value
161
+
162
+ define_singleton_method(name) { @values[name] }
163
+ define_singleton_method(:"#{name}=") do |v|
164
+ @values[name] = v
165
+ end
166
+
167
+ define_singleton_method(:"#{name}?") { value } if [FalseClass, TrueClass].include?(value.class)
168
+ end
169
+
170
+ def remove_accessor(name)
171
+ @values.delete(name)
172
+
173
+ singleton_class.class_eval { remove_method name.to_sym } if singleton_methods.include?(name.to_sym)
174
+ singleton_class.class_eval { remove_method "#{name}=".to_sym } if singleton_methods.include?("#{name}=".to_sym)
175
+ singleton_class.class_eval { remove_method "#{name}?".to_sym } if singleton_methods.include?("#{name}?".to_sym)
176
+ end
177
+
178
+ end
179
+ end
@@ -0,0 +1,3 @@
1
+ module Hawkei # :nodoc:
2
+ LIBRARY_NAME = 'hawkei'.freeze
3
+ end
@@ -0,0 +1,79 @@
1
+ module Hawkei
2
+ ##
3
+ # == Hawkei \Message
4
+ #
5
+ # Return the base message for an event
6
+ class Message
7
+ class << self
8
+
9
+ def base
10
+ Util.deep_compact(
11
+ message_id: SecureRandom.uuid,
12
+ timestamp: Time.now.utc.iso8601(3),
13
+ session_tracker_id: session_tracker_id,
14
+ )
15
+ end
16
+
17
+ def extended
18
+ Util.deep_compact(
19
+ library: library,
20
+ server: server,
21
+ request: Hawkei::Store.get(:request),
22
+ worker: Hawkei::Store.get(:worker),
23
+ environment: Hawkei::Store.get(:environment) || Hawkei.configurations.environment_name,
24
+ metadata: metadata
25
+ ).merge(base)
26
+ end
27
+
28
+ private
29
+
30
+ def session_tracker_id
31
+ return Hawkei::Store.get(:session_tracker_id) if Hawkei::Store.exist?(:session_tracker_id)
32
+
33
+ Hawkei::Store.set(:session_tracker_id, SecureRandom.uuid)
34
+ end
35
+
36
+ def library
37
+ {
38
+ name: Hawkei::LIBRARY_NAME,
39
+ language: 'ruby',
40
+ version: Hawkei::VERSION,
41
+ }
42
+ end
43
+
44
+ def server
45
+ {
46
+ host: Socket.gethostname,
47
+ pid: Process.pid,
48
+ software: Hawkei::Store.get(:server_software) || program_name,
49
+ }
50
+ end
51
+
52
+ def program_name
53
+ name = $PROGRAM_NAME
54
+
55
+ name.split('/').last
56
+ rescue StandardError => _e
57
+ name
58
+ end
59
+
60
+ def metadata
61
+ return nil if Hawkei.configurations.metadata.nil?
62
+
63
+ Hawkei.configurations.metadata.each_with_object({}) do |(key, value), hash|
64
+ if value.is_a?(Proc)
65
+ begin
66
+ hash[key] = value.call
67
+ rescue StandardError => _e
68
+ nil
69
+ end
70
+ next
71
+ end
72
+
73
+ hash[key] = value
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,139 @@
1
+ require 'uri'
2
+
3
+ module Hawkei
4
+ module Plugins
5
+ module Rack
6
+ ##
7
+ # Hawkei \Plugins \Rack \Middleware
8
+ #
9
+ # Middleware for Rack
10
+ #
11
+ class Middleware
12
+
13
+ def initialize(app)
14
+ @app = app
15
+ end
16
+
17
+ def call(env)
18
+ request = ::Rack::Request.new(env)
19
+
20
+ store_tracker(request)
21
+ store_request_data(request, env)
22
+
23
+ Hawkei::Plugins::Rails::MiddlewareData.store_data(request) if defined?(::Rails)
24
+ status, headers, body = @app.call(env)
25
+
26
+ write_cookie_session_tracker_id!(headers)
27
+ [status, headers, body]
28
+ ensure
29
+ Hawkei::Store.clear! unless env['hawkei_test']
30
+ end
31
+
32
+ private
33
+
34
+ def session_tracker_id_name
35
+ '_hawkei_stid'.freeze
36
+ end
37
+
38
+ def store_tracker(request)
39
+ Hawkei::Store.set(
40
+ :session_tracker_id,
41
+ request.cookies[session_tracker_id_name] || SecureRandom.uuid
42
+ )
43
+ end
44
+
45
+ def store_request_data(request, env)
46
+ Hawkei::Store.set(
47
+ :request,
48
+ url: obfuscate_uri(request.url),
49
+ ssl: request.ssl?,
50
+ host: request.host,
51
+ port: request.port,
52
+ path: request.path,
53
+ referrer: obfuscate_uri(request.referrer),
54
+ method: request.request_method,
55
+ xhr: request.xhr?,
56
+ user_agent: request.user_agent,
57
+ ip: request.ip,
58
+ get_params: obfuscation_get_params(request, 'GET'),
59
+ post_params: obfuscation_get_params(request, 'POST'),
60
+ headers: obfuscate_headers(env)
61
+ )
62
+
63
+ Hawkei::Store.bulk_set(
64
+ server_software: request.env['SERVER_SOFTWARE']
65
+ )
66
+ end
67
+
68
+ def write_cookie_session_tracker_id!(headers)
69
+ ::Rack::Utils.set_cookie_header!(
70
+ headers || {},
71
+ session_tracker_id_name,
72
+ Util.deep_compact(
73
+ value: Hawkei::Store.get(:session_tracker_id),
74
+ path: '/',
75
+ domain: Hawkei.configurations.domain,
76
+ http_only: false,
77
+ max_age: (10 * 365 * 24 * 60 * 60),
78
+ )
79
+ )
80
+ end
81
+
82
+ def obfuscate_uri(url)
83
+ uri = URI.parse(url)
84
+
85
+ params =
86
+ Util.deep_obfuscate_value(
87
+ ::Rack::Utils.parse_query(uri.query),
88
+ Hawkei.configurations.obfuscated_fields,
89
+ 'HIDDEN'
90
+ )
91
+
92
+ return url if params.empty?
93
+
94
+ uri.merge(
95
+ "?#{::Rack::Utils.build_query(params)}"
96
+ ).to_s
97
+ rescue StandardError => _e
98
+ ''
99
+ end
100
+
101
+ def obfuscation_get_params(request, type)
102
+ Util.deep_obfuscate_value(
103
+ request.send(type),
104
+ Hawkei.configurations.obfuscated_fields
105
+ )
106
+ rescue StandardError => _e
107
+ {}
108
+ end
109
+
110
+ def https_request?(env)
111
+ env['HTTPS'] == 'on' ||
112
+ env['HTTP_X_FORWARDED_SSL'] == 'on' ||
113
+ env['HTTP_X_FORWARDED_PROTO'].to_s.split(',').first == 'https' ||
114
+ env['rack.url_scheme'] == 'https'
115
+ end
116
+
117
+ def obfuscate_headers(env)
118
+ skip_headers = %w[HTTP_COOKIE]
119
+
120
+ headers = env.keys.grep(/^HTTP_|^CONTENT_/).each_with_object({}) do |key, hash|
121
+ next if skip_headers.include?(key)
122
+
123
+ name = key.gsub(/^HTTP_/, '').split('_').map(&:capitalize).join('-')
124
+
125
+ hash[name] = env[key]
126
+ end
127
+
128
+ Util.deep_obfuscate_value(
129
+ headers,
130
+ Hawkei.configurations.obfuscated_fields
131
+ )
132
+ rescue StandardError => _e
133
+ {}
134
+ end
135
+
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,19 @@
1
+ module Hawkei
2
+ module Plugins
3
+ module Rails
4
+ class Data
5
+
6
+ class << self
7
+
8
+ def store_data
9
+ Hawkei::Store.bulk_set(
10
+ environment: ::Rails.env
11
+ )
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ module Hawkei
2
+ module Plugins
3
+ module Rails
4
+ class MiddlewareData
5
+
6
+ class << self
7
+
8
+ def store_data(request = nil)
9
+ store_request_data(request) if request
10
+ end
11
+
12
+ private
13
+
14
+ def store_request_data(request)
15
+ object = Hawkei::Store.get(:request) || {}
16
+
17
+ Hawkei::Store.set(
18
+ :request,
19
+ object.merge(id: request.env['action_dispatch.request_id'])
20
+ )
21
+ end
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module Hawkei
2
+ module Plugins
3
+ module Rails
4
+ class Railtie < ::Rails::Railtie
5
+
6
+ initializer 'hawkei.middleware' do |app|
7
+ app.config.middleware.use(Hawkei::Plugins::Rack::Middleware)
8
+
9
+ if ActiveSupport.const_defined?(:Reloader) && ActiveSupport::Reloader.respond_to?(:to_complete)
10
+ ActiveSupport::Reloader.to_complete do
11
+ Hawkei::Store.clear!
12
+ end
13
+ elsif ActionDispatch.const_defined?(:Reloader) && ActionDispatch::Reloader.respond_to?(:to_cleanup)
14
+ ActionDispatch::Reloader.to_cleanup do
15
+ Hawkei::Store.clear!
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module Hawkei
2
+ module Plugins
3
+ module Sidekiq
4
+ ##
5
+ # Hawkei \Plugins \Sidekiq \Client \Middleware
6
+ #
7
+ # Client middleware for sidekiq
8
+ #
9
+ class ClientMiddleware
10
+
11
+ def call(_worker_class, job, _queue, _redis_pool)
12
+ job['_hawkei_stid'] = Hawkei::Store.store[:session_tracker_id]
13
+ yield
14
+ end
15
+
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ require 'hawkei/plugins/sidekiq/client_middleware'
2
+ require 'hawkei/plugins/sidekiq/server_middleware'
3
+
4
+ Sidekiq.configure_client do |config|
5
+ config.client_middleware do |chain|
6
+ chain.add Hawkei::Plugins::Sidekiq::ClientMiddleware
7
+ end
8
+ end
9
+
10
+ Sidekiq.configure_server do |config|
11
+ config.server_middleware do |chain|
12
+ chain.add Hawkei::Plugins::Sidekiq::ServerMiddleware
13
+ end
14
+ end
@@ -0,0 +1,48 @@
1
+ module Hawkei
2
+ module Plugins
3
+ module Sidekiq
4
+ ##
5
+ # Hawkei \Plugins \Sidekiq \Server \Middleware
6
+ #
7
+ # Server middleware for sidekiq
8
+ #
9
+ class ServerMiddleware
10
+
11
+ def call(_worker, job, _queue)
12
+ Hawkei::Store.set(:session_tracker_id, job['_hawkei_stid'] || SecureRandom.uuid)
13
+ Hawkei::Store.set(:server_software, "Sidekiq #{::Sidekiq::VERSION}")
14
+ store_worker_data(job)
15
+ yield
16
+ ensure
17
+ Hawkei::Store.clear!
18
+ end
19
+
20
+ private
21
+
22
+ def store_worker_data(job)
23
+ Hawkei::Store.set(
24
+ :worker,
25
+ name: 'sidekiq',
26
+ version: ::Sidekiq::VERSION,
27
+ queue: job['queue'],
28
+ class: job['class'],
29
+ id: job['jid'],
30
+ created_at: convert_to_iso8601(job['created_at']),
31
+ process_at: convert_to_iso8601(job['enqueued_at']),
32
+ args: job['args'],
33
+ retried: job['retry_count'].is_a?(Integer),
34
+ retry_number: job['retry_count'],
35
+ failed_at: convert_to_iso8601(job['failed_at'])
36
+ )
37
+ end
38
+
39
+ def convert_to_iso8601(int_time)
40
+ Time.at(int_time).utc.iso8601(3)
41
+ rescue StandardError => _e
42
+ nil
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ ##
2
+ # Rack & Rails
3
+ #
4
+ if defined?(Rack)
5
+ require 'hawkei/plugins/rack/middleware'
6
+
7
+ if defined?(Rails)
8
+ require 'hawkei/plugins/rails/railtie'
9
+ require 'hawkei/plugins/rails/middleware_data'
10
+ require 'hawkei/plugins/rails/data'
11
+ end
12
+ end
13
+
14
+ ##
15
+ # Sidekiq
16
+ #
17
+ require 'hawkei/plugins/sidekiq/load' if defined?(Sidekiq)
@@ -0,0 +1,50 @@
1
+ module Hawkei
2
+ module Processor
3
+ class Async
4
+
5
+ def initialize
6
+ @queue = Queue.new
7
+ @state_worker = Concurrent::AtomicBoolean.new(true)
8
+ @worker = Worker.new(@queue, @state_worker)
9
+
10
+ at_exit do
11
+ shutdown_worker if worker_running?
12
+ end
13
+ end
14
+
15
+ def enqueue(attributes)
16
+ ensure_worker_running
17
+
18
+ @queue << attributes
19
+
20
+ true
21
+ end
22
+
23
+ private
24
+
25
+ def shutdown_worker
26
+ @state_worker.make_false
27
+ @queue << Hawkei::Processor::Worker::SHUTDOWN_MESSAGE
28
+ @worker_thread.wait
29
+
30
+ executor.shutdown
31
+ executor.wait_for_termination
32
+ end
33
+
34
+ def executor
35
+ @executor ||= Concurrent.global_io_executor
36
+ end
37
+
38
+ def ensure_worker_running
39
+ return if worker_running?
40
+
41
+ @worker_thread = Concurrent::Future.execute { @worker.run }
42
+ end
43
+
44
+ def worker_running?
45
+ @worker_thread && @worker_thread.incomplete?
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,84 @@
1
+ module Hawkei
2
+ module Processor
3
+ class Batch
4
+
5
+ attr_reader :messages
6
+
7
+ MAX_BYTES = 204_800 # 200Kb
8
+ MAX_MESSAGES = 100
9
+ MAX_MESSAGE_BYTES = 32_768 # 32Kb
10
+
11
+ DEFAULT_RETRY_TIME = 60
12
+
13
+ MAX_RETRY = 10
14
+ RETRY_MAP = {
15
+ 1 => 2,
16
+ 2 => 5,
17
+ 3 => 10,
18
+ 4 => 20,
19
+ 5 => 30,
20
+ 6 => 30,
21
+ 7 => 30,
22
+ 8 => 30,
23
+ 9 => 30,
24
+ 10 => 30,
25
+ }.freeze
26
+
27
+ def initialize
28
+ @retry_count = 0
29
+ @total_bytes = 0
30
+ @messages = []
31
+ end
32
+
33
+ def <<(message)
34
+ message_json_size = message.to_json.bytesize
35
+
36
+ if max_message_reached?(message_json_size)
37
+ Hawkei.configurations.logger.error('Message is too big to be send')
38
+ return false
39
+ end
40
+
41
+ @total_bytes += message_json_size
42
+
43
+ @messages << message
44
+
45
+ true
46
+ end
47
+
48
+ def empty?
49
+ @messages.size.zero?
50
+ end
51
+
52
+ def full?
53
+ max_messages_reached? || max_size_reached?
54
+ end
55
+
56
+ def next_retry
57
+ RETRY_MAP[@retry_count] || DEFAULT_RETRY_TIME
58
+ end
59
+
60
+ def update_retry
61
+ @retry_count += 1
62
+ end
63
+
64
+ def can_retry?
65
+ @retry_count < MAX_RETRY
66
+ end
67
+
68
+ private
69
+
70
+ def max_messages_reached?
71
+ @messages.length >= MAX_MESSAGES
72
+ end
73
+
74
+ def max_size_reached?
75
+ @total_bytes >= MAX_BYTES
76
+ end
77
+
78
+ def max_message_reached?(message_json_size)
79
+ message_json_size > MAX_MESSAGE_BYTES
80
+ end
81
+
82
+ end
83
+ end
84
+ end