hawkei 1.0.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.
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