liveqa 1.8.3 → 1.9.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 +4 -4
- data/.rubocop.yml +8 -2
- data/.travis.yml +0 -1
- data/LICENCE +21 -0
- data/README.md +10 -117
- data/lib/liveqa/api_resource.rb +7 -3
- data/lib/liveqa/batch.rb +18 -0
- data/lib/liveqa/config.rb +13 -21
- data/lib/liveqa/event.rb +1 -1
- data/lib/liveqa/formated_logger.rb +45 -0
- data/lib/liveqa/message.rb +3 -3
- data/lib/liveqa/plugins/rack/middleware.rb +3 -3
- data/lib/liveqa/plugins/sidekiq/server_middleware.rb +1 -1
- data/lib/liveqa/processor/async.rb +48 -0
- data/lib/liveqa/processor/batch.rb +81 -0
- data/lib/liveqa/processor/worker.rb +66 -0
- data/lib/liveqa/util.rb +3 -3
- data/lib/liveqa/version.rb +1 -1
- data/lib/liveqa.rb +66 -33
- data/liveqa.gemspec +3 -3
- data/spec/lib/liveqa/api_resource_spec.rb +8 -8
- data/spec/lib/liveqa/batch_spec.rb +14 -0
- data/spec/lib/liveqa/config_spec.rb +9 -15
- data/spec/lib/liveqa/formated_logger_spec.rb +99 -0
- data/spec/lib/liveqa/processor/async_spec.rb +19 -0
- data/spec/lib/liveqa/processor/batch_spec.rb +48 -0
- data/spec/lib/liveqa/processor/worker_spec.rb +25 -0
- data/spec/lib/liveqa_spec.rb +133 -40
- metadata +26 -16
- data/lib/liveqa/async_handlers/base.rb +0 -15
- data/lib/liveqa/async_handlers/sidekiq.rb +0 -33
- data/spec/lib/liveqa/async_handlers/base_spec.rb +0 -29
- data/spec/lib/liveqa/async_handlers/sidekiq_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e2af9cc4ebfb7e97a8330c769db5ffb49989ec9
|
4
|
+
data.tar.gz: 4261ba5bbe8cbebd535f876fe9f8762e460286cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f5fc2bd622bdf4e98573f3205ced2fce4ae9b569e398ab28633654cffaf2a3c1e2532c63da9f8352bcc74482d787fd6958104d0c02d52afe83baf3596374595
|
7
|
+
data.tar.gz: 7e2fccdb0c9a117a852989f3ab3e7744b958a0f31f3014cff519614492b3d3cdc862956e375ef6f715c747908170674708ca034a2b578d41201b3c9034f84a91
|
data/.rubocop.yml
CHANGED
@@ -22,7 +22,13 @@ Layout/EmptyLinesAroundBlockBody:
|
|
22
22
|
|
23
23
|
Style/FrozenStringLiteralComment:
|
24
24
|
Enabled: false
|
25
|
-
Style/
|
25
|
+
Style/MissingRespondToMissing:
|
26
|
+
Enabled: false
|
27
|
+
Style/TrailingCommaInHashLiteral:
|
28
|
+
EnforcedStyleForMultiline: comma
|
29
|
+
Style/TrailingCommaInArrayLiteral:
|
30
|
+
EnforcedStyleForMultiline: comma
|
31
|
+
Style/TrailingCommaInArguments:
|
26
32
|
Enabled: false
|
27
33
|
|
28
34
|
Documentation:
|
@@ -32,7 +38,7 @@ Bundler/DuplicatedGem:
|
|
32
38
|
Enabled: false
|
33
39
|
|
34
40
|
AllCops:
|
35
|
-
TargetRubyVersion: 2.
|
41
|
+
TargetRubyVersion: 2.2
|
36
42
|
Exclude:
|
37
43
|
- 'spec/**/*'
|
38
44
|
Exclude:
|
data/.travis.yml
CHANGED
data/LICENCE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018- LiveQA, Inc. (https://www.liveqa.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,127 +1,20 @@
|
|
1
1
|
# LiveQA
|
2
2
|
|
3
|
-
[](https://travis-ci.org/LiveQA/liveqa-ruby)
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
```sh
|
10
|
-
gem install liveqa
|
11
|
-
```
|
12
|
-
|
13
|
-
For Rails in your Gemfile
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
gem 'liveqa'
|
17
|
-
```
|
18
|
-
|
19
|
-
## Configuration
|
20
|
-
|
21
|
-
```ruby
|
22
|
-
LiveQA.configure do |config|
|
23
|
-
##
|
24
|
-
# Account token can be found inside your environment settings
|
25
|
-
config.account_token = 'acc_xx'
|
26
|
-
|
27
|
-
##
|
28
|
-
# The name of your space
|
29
|
-
config.space_name = 'LiveQA'
|
30
|
-
|
31
|
-
##
|
32
|
-
# The name of your environement
|
33
|
-
config.environment_name = 'production'
|
34
|
-
|
35
|
-
##
|
36
|
-
# If you use a proxy.
|
37
|
-
# default: nil
|
38
|
-
# config.proxy_url = ENV['HTTP_PROXY']
|
39
|
-
|
40
|
-
##
|
41
|
-
# If enabled is set to false nothing is send to the server
|
42
|
-
# default: true
|
43
|
-
# config.enabled = true
|
44
|
-
|
45
|
-
##
|
46
|
-
# Extra attributes to be obfuscated
|
47
|
-
# default: []
|
48
|
-
# config.obfuscated_fields = ['credit_card_number']
|
49
|
-
|
50
|
-
##
|
51
|
-
# Use an async handler to send data to the liveqa to
|
52
|
-
# avoid slowing down your application
|
53
|
-
# available option: :sidekiq
|
54
|
-
# default: nil
|
55
|
-
# config.async_handler = :sidekiq
|
56
|
-
|
57
|
-
##
|
58
|
-
# Options to be passed to the async handler
|
59
|
-
# default: {}
|
60
|
-
# config.async_options = { queue: 'liveqa' }
|
5
|
+
[LiveQA](https://www.liveqa.io) Ruby library
|
61
6
|
|
62
|
-
|
63
|
-
# Metadata is passed with every request to the server
|
64
|
-
# default: nil
|
65
|
-
# config.metadata = {
|
66
|
-
#. customer: -> { current_customer.id},
|
67
|
-
#. version: 42
|
68
|
-
# }
|
69
|
-
#
|
70
|
-
end
|
71
|
-
```
|
7
|
+
Our Ruby library let's you interact easily with our API. All the request will go to our servers and will be display processed and display inside our debugger.
|
72
8
|
|
73
|
-
##
|
9
|
+
## Setup
|
74
10
|
|
75
|
-
|
11
|
+
- [Start by creating an account](https://www.liveqa.io/register)
|
12
|
+
- Follow the [Quick Start Guide](https://docs.liveqa.io/docs/quick-start) to get set up
|
13
|
+
- Use our [Ruby Library](https://docs.liveqa.io/docs/ruby) to install and configure LiveQA for your platform.
|
76
14
|
|
77
|
-
Track an event
|
78
15
|
|
79
|
-
|
16
|
+
## Documentation & Usage
|
80
17
|
|
81
|
-
|
82
|
-
* `Hash` event attributes
|
18
|
+
Documentation is available at [docs.liveqa.io/docs/ruby](https://docs.liveqa.io/docs/ruby)
|
83
19
|
|
84
|
-
|
85
|
-
LiveQA.track('my event',
|
86
|
-
user_id: 42,
|
87
|
-
properties: {
|
88
|
-
order_id: 84
|
89
|
-
}
|
90
|
-
);
|
91
|
-
```
|
92
|
-
|
93
|
-
### Identify
|
94
|
-
|
95
|
-
Identify a user
|
96
|
-
|
97
|
-
Attributes:
|
98
|
-
|
99
|
-
* `String` user id from your database
|
100
|
-
* `Hash` user attributes
|
101
|
-
|
102
|
-
```ruby
|
103
|
-
LiveQA.identify(42,
|
104
|
-
properties: {
|
105
|
-
name: 'John Doe'
|
106
|
-
}
|
107
|
-
);
|
108
|
-
```
|
109
|
-
|
110
|
-
### Watch
|
111
|
-
|
112
|
-
Create a watcher
|
113
|
-
|
114
|
-
Attributes:
|
115
|
-
|
116
|
-
* `String|Integer` template flow name or id
|
117
|
-
* `Hash` watcher attributes
|
118
|
-
|
119
|
-
```ruby
|
120
|
-
LiveQA.watch('My Flow',
|
121
|
-
expected_times: 42
|
122
|
-
);
|
123
|
-
```
|
124
|
-
|
125
|
-
## Issues
|
126
|
-
|
127
|
-
If you have any issue you can report them on github, or contact support@liveqa.io
|
20
|
+
LiveQA ruby integration for [LiveQA](https://www.liveqa.io)
|
data/lib/liveqa/api_resource.rb
CHANGED
@@ -60,7 +60,9 @@ module LiveQA
|
|
60
60
|
#
|
61
61
|
# @return [Hash] response
|
62
62
|
# @raise [LiveQA::RequestError] if the request is invalid
|
63
|
+
# rubocop:disable Metrics/AbcSize
|
63
64
|
def request(method, path, payload = {}, options = {})
|
65
|
+
payload[:sent_at] = Time.now.utc.iso8601(3)
|
64
66
|
payload = Util.deep_obfuscate_value(payload, configurations.obfuscated_fields)
|
65
67
|
url_params = Util.encode_parameters(payload) if method == :get
|
66
68
|
uri = build_endpoint_url(path, url_params)
|
@@ -76,7 +78,9 @@ module LiveQA
|
|
76
78
|
Request.execute(request_options).body
|
77
79
|
rescue LiveQA::RequestError => error
|
78
80
|
return error.http_body if error.http_status == 422
|
81
|
+
raise
|
79
82
|
end
|
83
|
+
# rubocop:enable Metrics/AbcSize
|
80
84
|
|
81
85
|
private
|
82
86
|
|
@@ -99,7 +103,7 @@ module LiveQA
|
|
99
103
|
return {} unless configurations.http_secure
|
100
104
|
{
|
101
105
|
ca_file: File.expand_path(File.dirname(__FILE__) + '/../../vendor/cacert.pem'),
|
102
|
-
verify_mode: OpenSSL::SSL::VERIFY_PEER
|
106
|
+
verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
103
107
|
}
|
104
108
|
end
|
105
109
|
|
@@ -110,8 +114,8 @@ module LiveQA
|
|
110
114
|
content_type: 'application/json',
|
111
115
|
x_account_token: options.delete(:account_token) || configurations.account_token,
|
112
116
|
x_space_name: options.delete(:space_name) || configurations.space_name,
|
113
|
-
x_environment_name: options.delete(:environment_name) || configurations.environment_name
|
114
|
-
}
|
117
|
+
x_environment_name: options.delete(:environment_name) || configurations.environment_name,
|
118
|
+
},
|
115
119
|
}
|
116
120
|
end
|
117
121
|
|
data/lib/liveqa/batch.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module LiveQA
|
2
|
+
##
|
3
|
+
# == LiveQA \Batch
|
4
|
+
#
|
5
|
+
# Accepted Methods:
|
6
|
+
#
|
7
|
+
# * create
|
8
|
+
#
|
9
|
+
# @example: Usage
|
10
|
+
#
|
11
|
+
# request = LiveQA::Batch.create(...) #=> #<LiveQA::Response...>
|
12
|
+
#
|
13
|
+
class Batch < APIResource
|
14
|
+
@resource_name = 'batches'
|
15
|
+
|
16
|
+
include LiveQA::APIOperation::Save
|
17
|
+
end
|
18
|
+
end
|
data/lib/liveqa/config.rb
CHANGED
@@ -5,13 +5,6 @@ module LiveQA
|
|
5
5
|
# Represent the LiveQA configuration for the API
|
6
6
|
class Config
|
7
7
|
|
8
|
-
ASYNC_HANDLERS = {
|
9
|
-
sidekiq: {
|
10
|
-
class: 'LiveQA::AsyncHandlers::Sidekiq',
|
11
|
-
require: 'liveqa/async_handlers/sidekiq'
|
12
|
-
}
|
13
|
-
}.freeze
|
14
|
-
|
15
8
|
DEFAULT_OBFUSCATED_FIELDS = %w[
|
16
9
|
password
|
17
10
|
password_confirmation
|
@@ -63,12 +56,8 @@ module LiveQA
|
|
63
56
|
attr_accessor :obfuscated_fields
|
64
57
|
|
65
58
|
##
|
66
|
-
# @return [
|
67
|
-
attr_accessor :
|
68
|
-
|
69
|
-
##
|
70
|
-
# @return [Hash] options for asynchronous handler
|
71
|
-
attr_accessor :async_options
|
59
|
+
# @return [Boolean] send
|
60
|
+
attr_accessor :async
|
72
61
|
|
73
62
|
##
|
74
63
|
# @return [Hash] custom object properties
|
@@ -78,6 +67,14 @@ module LiveQA
|
|
78
67
|
# @return [Hash] metadata to be attach to the payload
|
79
68
|
attr_accessor :metadata
|
80
69
|
|
70
|
+
##
|
71
|
+
# @return [Boolean] enable the logger
|
72
|
+
attr_accessor :log
|
73
|
+
|
74
|
+
##
|
75
|
+
# @return [Logger] logger
|
76
|
+
attr_accessor :logger
|
77
|
+
|
81
78
|
##
|
82
79
|
# @param [Hash{Symbol=>Object}]
|
83
80
|
# Initialize and validate the configuration
|
@@ -93,10 +90,11 @@ module LiveQA
|
|
93
90
|
self.http_secure = options[:http_secure] || true
|
94
91
|
self.enabled = options[:enabled] || true
|
95
92
|
self.obfuscated_fields = options[:obfuscated_fields] || []
|
96
|
-
self.
|
97
|
-
self.async_options = options[:async_options] || {}
|
93
|
+
self.async = options[:async] || true
|
98
94
|
self.custom_object_properties = options[:custom_object_properties] || {}
|
99
95
|
self.metadata = options[:metadata]
|
96
|
+
self.log = options[:log] || true
|
97
|
+
self.logger = FormatedLogger.build(options[:logger])
|
100
98
|
end
|
101
99
|
# rubocop:enable Metrics/CyclomaticComplexity
|
102
100
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -121,15 +119,9 @@ module LiveQA
|
|
121
119
|
# Format configuration fields
|
122
120
|
#
|
123
121
|
# * Set obfuscated_fields to string
|
124
|
-
# * Change to the class for async handler
|
125
122
|
#
|
126
123
|
def format!
|
127
124
|
self.obfuscated_fields = (obfuscated_fields.map(&:to_s) + DEFAULT_OBFUSCATED_FIELDS).uniq
|
128
|
-
|
129
|
-
return unless ASYNC_HANDLERS[async_handler]
|
130
|
-
|
131
|
-
require ASYNC_HANDLERS[async_handler][:require]
|
132
|
-
self.async_handler = Object.const_get(ASYNC_HANDLERS[async_handler][:class]).new(async_options)
|
133
125
|
end
|
134
126
|
|
135
127
|
def validate_presence(field)
|
data/lib/liveqa/event.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module LiveQA
|
2
|
+
##
|
3
|
+
# Display formated log
|
4
|
+
class FormatedLogger
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def build(logger)
|
9
|
+
return new(logger) if logger
|
10
|
+
return new(Rails.logger) if defined?(Rails)
|
11
|
+
|
12
|
+
new(::Logger.new(STDOUT))
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :logger
|
18
|
+
|
19
|
+
PREFIX = '[LiveQA]'.freeze
|
20
|
+
METHODS = %i[debug info warn error].freeze
|
21
|
+
|
22
|
+
def initialize(logger)
|
23
|
+
@logger = logger
|
24
|
+
end
|
25
|
+
|
26
|
+
METHODS.each do |method|
|
27
|
+
define_method(method) do |message|
|
28
|
+
log(method, message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def log(type, message)
|
35
|
+
return unless configurations.log
|
36
|
+
|
37
|
+
logger.send(type, "#{PREFIX} #{message}")
|
38
|
+
end
|
39
|
+
|
40
|
+
def configurations
|
41
|
+
LiveQA.configurations
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
data/lib/liveqa/message.rb
CHANGED
@@ -37,7 +37,7 @@ module LiveQA
|
|
37
37
|
{
|
38
38
|
name: LiveQA::LIBRARY_NAME,
|
39
39
|
language: 'ruby',
|
40
|
-
version: LiveQA::VERSION
|
40
|
+
version: LiveQA::VERSION,
|
41
41
|
}
|
42
42
|
end
|
43
43
|
|
@@ -45,7 +45,7 @@ module LiveQA
|
|
45
45
|
{
|
46
46
|
host: Socket.gethostname,
|
47
47
|
pid: Process.pid,
|
48
|
-
software: LiveQA::Store.get(:server_software)
|
48
|
+
software: LiveQA::Store.get(:server_software),
|
49
49
|
}
|
50
50
|
end
|
51
51
|
|
@@ -56,7 +56,7 @@ module LiveQA
|
|
56
56
|
if value.is_a?(Proc)
|
57
57
|
begin
|
58
58
|
hash[key] = value.call
|
59
|
-
rescue
|
59
|
+
rescue StandardError => _e
|
60
60
|
nil
|
61
61
|
end
|
62
62
|
next
|
@@ -90,7 +90,7 @@ module LiveQA
|
|
90
90
|
uri.merge(
|
91
91
|
"?#{::Rack::Utils.build_query(params)}"
|
92
92
|
).to_s
|
93
|
-
rescue
|
93
|
+
rescue StandardError => _e
|
94
94
|
''
|
95
95
|
end
|
96
96
|
|
@@ -99,7 +99,7 @@ module LiveQA
|
|
99
99
|
request.send(type),
|
100
100
|
LiveQA.configurations.obfuscated_fields
|
101
101
|
)
|
102
|
-
rescue
|
102
|
+
rescue StandardError => _e
|
103
103
|
{}
|
104
104
|
end
|
105
105
|
|
@@ -125,7 +125,7 @@ module LiveQA
|
|
125
125
|
headers,
|
126
126
|
LiveQA.configurations.obfuscated_fields
|
127
127
|
)
|
128
|
-
rescue
|
128
|
+
rescue StandardError => _e
|
129
129
|
{}
|
130
130
|
end
|
131
131
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module LiveQA
|
2
|
+
module Processor
|
3
|
+
class Async
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@max_queue_size = 10_000
|
7
|
+
@queue = Queue.new
|
8
|
+
@worker = Worker.new(@queue)
|
9
|
+
@worker_mutex = Mutex.new
|
10
|
+
|
11
|
+
at_exit do
|
12
|
+
@worker_thread && @worker_thread[:should_exit] = true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def enqueue(attributes)
|
17
|
+
return false if @queue.length > @max_queue_size
|
18
|
+
|
19
|
+
@queue << attributes
|
20
|
+
ensure_worker_running
|
21
|
+
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def flush
|
26
|
+
while !@queue.empty? || @worker.is_requesting?
|
27
|
+
ensure_worker_running
|
28
|
+
sleep(0.1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def ensure_worker_running
|
35
|
+
return if worker_running?
|
36
|
+
@worker_mutex.synchronize do
|
37
|
+
return if worker_running?
|
38
|
+
@worker_thread = Thread.new { @worker.run }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def worker_running?
|
43
|
+
@worker_thread && @worker_thread.alive?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module LiveQA
|
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
|
+
MAX_RETRY = 10
|
12
|
+
RETRY_MAP = {
|
13
|
+
1 => 2,
|
14
|
+
2 => 5,
|
15
|
+
3 => 10,
|
16
|
+
4 => 20,
|
17
|
+
5 => 30,
|
18
|
+
6 => 30,
|
19
|
+
7 => 30,
|
20
|
+
8 => 30,
|
21
|
+
9 => 30,
|
22
|
+
10 => 30,
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@retry_count = 0
|
27
|
+
@total_bytes = 0
|
28
|
+
@messages = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def <<(message)
|
32
|
+
message_json_size = message.to_json.bytesize
|
33
|
+
|
34
|
+
if max_message_reached?(message_json_size)
|
35
|
+
LiveQA.configurations.logger.error('Message is too big to be send')
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
|
39
|
+
@total_bytes += message_json_size
|
40
|
+
|
41
|
+
@messages << message
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def full?
|
47
|
+
max_messages_reached? || max_size_reached?
|
48
|
+
end
|
49
|
+
|
50
|
+
def update_retry
|
51
|
+
@retry_count += 1
|
52
|
+
@retry_at = Time.now + (RETRY_MAP[@retry_count] || 120)
|
53
|
+
end
|
54
|
+
|
55
|
+
def can_run?
|
56
|
+
return true if @retry_count.zero?
|
57
|
+
|
58
|
+
Time.now >= @retry_at
|
59
|
+
end
|
60
|
+
|
61
|
+
def can_retry?
|
62
|
+
@retry_count < MAX_RETRY
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def max_messages_reached?
|
68
|
+
@messages.length >= MAX_MESSAGES
|
69
|
+
end
|
70
|
+
|
71
|
+
def max_size_reached?
|
72
|
+
@total_bytes >= MAX_BYTES
|
73
|
+
end
|
74
|
+
|
75
|
+
def max_message_reached?(message_json_size)
|
76
|
+
message_json_size > MAX_MESSAGE_BYTES
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module LiveQA
|
2
|
+
module Processor
|
3
|
+
class Worker
|
4
|
+
|
5
|
+
DEFAULT_WAIT_TIME = 2
|
6
|
+
|
7
|
+
attr_reader :queue
|
8
|
+
attr_reader :lock
|
9
|
+
attr_reader :batches
|
10
|
+
|
11
|
+
def initialize(queue)
|
12
|
+
@queue = queue
|
13
|
+
@lock = Mutex.new
|
14
|
+
@batches = []
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
until Thread.current[:should_exit]
|
19
|
+
return if queue.empty? && batches.empty?
|
20
|
+
|
21
|
+
sleep(DEFAULT_WAIT_TIME) if queue.empty?
|
22
|
+
|
23
|
+
create_new_batch unless queue.empty?
|
24
|
+
|
25
|
+
send_batches
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def create_new_batch
|
32
|
+
batch = Batch.new
|
33
|
+
lock.synchronize do
|
34
|
+
batch << queue.pop until batch.full? || queue.empty?
|
35
|
+
end
|
36
|
+
batches.push(batch)
|
37
|
+
end
|
38
|
+
|
39
|
+
def send_batches
|
40
|
+
batches.dup.each do
|
41
|
+
batch = batches.pop
|
42
|
+
|
43
|
+
unless batch.can_run?
|
44
|
+
batches.push(batch)
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
begin
|
49
|
+
LiveQA::Batch.create(Message.base.merge(data: batch.messages))
|
50
|
+
rescue LiveQA::RequestError => error
|
51
|
+
return LiveQA.configurations.logger.error(error.message) if [401, 404].include?(error.http_status)
|
52
|
+
batch_retry(batch)
|
53
|
+
rescue Errno::ECONNREFUSED => _error
|
54
|
+
batch_retry(batch)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def batch_retry(batch)
|
60
|
+
batch.update_retry
|
61
|
+
batches.push(batch) if batch.can_retry?
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/liveqa/util.rb
CHANGED
@@ -94,7 +94,7 @@ module LiveQA
|
|
94
94
|
deep_transform_keys_in_object(hash_object) do |key|
|
95
95
|
begin
|
96
96
|
underscore(key).to_sym
|
97
|
-
rescue
|
97
|
+
rescue StandardError => _e
|
98
98
|
key
|
99
99
|
end
|
100
100
|
end
|
@@ -110,7 +110,7 @@ module LiveQA
|
|
110
110
|
deep_transform_keys_in_object(hash_object) do |key|
|
111
111
|
begin
|
112
112
|
key.to_s
|
113
|
-
rescue
|
113
|
+
rescue StandardError => _e
|
114
114
|
key
|
115
115
|
end
|
116
116
|
end
|
@@ -126,7 +126,7 @@ module LiveQA
|
|
126
126
|
deep_transform_keys_in_object(hash_object) do |key|
|
127
127
|
begin
|
128
128
|
key.to_sym
|
129
|
-
rescue
|
129
|
+
rescue StandardError => _e
|
130
130
|
key
|
131
131
|
end
|
132
132
|
end
|
data/lib/liveqa/version.rb
CHANGED