boxxspring-workers 1.2.0 → 1.5.2
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 +5 -5
- data/lib/boxxspring-worker-version.rb +1 -1
- data/lib/boxxspring-worker.rb +2 -0
- data/lib/boxxspring/worker/authorization.rb +49 -0
- data/lib/boxxspring/worker/base.rb +11 -8
- data/lib/boxxspring/worker/error.rb +9 -0
- data/lib/boxxspring/worker/logging.rb +3 -2
- data/lib/boxxspring/worker/metrics.rb +28 -23
- data/lib/boxxspring/worker/task_base.rb +54 -80
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 592a7fe1d26ded3ac57107334b47832a35a0085ec11638a10b6ada575196c4d4
|
4
|
+
data.tar.gz: c375eb299997a3aa01cbe14e2ef92ebb2cbb171ab1082ffa7d380d49ff581e0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bd1cbbae7404c01a92913160b0c9667c38cccc78177da023f242f88e8ae12614f40ecd22e80d099a158091c7de56fc13ad0e90fcedc2cb00df3a671e33fcab5
|
7
|
+
data.tar.gz: c219d6f34bf58a994b3ad9fe4c59c71b63a90ef0238fe2af8f4bbd42909fec5a966474d0dc9d2b28014e67c4e0b3e3c561f90a3b61eacc275ef56c4c32882550
|
data/lib/boxxspring-worker.rb
CHANGED
@@ -7,12 +7,14 @@ require 'lib/boxxspring/journal'
|
|
7
7
|
require 'lib/boxxspring/worker'
|
8
8
|
require 'lib/boxxspring/worker/logging'
|
9
9
|
require 'lib/boxxspring/worker/metrics'
|
10
|
+
require 'lib/boxxspring/worker/error'
|
10
11
|
require 'lib/boxxspring/worker/metrics/metric_computer'
|
11
12
|
require 'lib/boxxspring/worker/metrics/microseconds_metric_computer'
|
12
13
|
require 'lib/boxxspring/worker/metrics/count_metric_computer'
|
13
14
|
require 'lib/boxxspring/worker/metrics/seconds_metric_computer'
|
14
15
|
require 'lib/boxxspring/worker/metrics/milliseconds_metric_computer'
|
15
16
|
require 'lib/boxxspring/worker/configuration'
|
17
|
+
require 'lib/boxxspring/worker/authorization'
|
16
18
|
require 'lib/boxxspring/worker/base'
|
17
19
|
require 'lib/boxxspring/worker/task_base'
|
18
20
|
require 'lib/boxxspring/synchronization/configuration'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Boxxspring
|
2
|
+
|
3
|
+
module Worker
|
4
|
+
|
5
|
+
module Authorization
|
6
|
+
|
7
|
+
def authorize( &block )
|
8
|
+
begin
|
9
|
+
retries ||= 3
|
10
|
+
block.call( token )
|
11
|
+
rescue Unimatrix::AuthorizationError => exception
|
12
|
+
if ( retries -= 1 ) > 0
|
13
|
+
token!
|
14
|
+
retry
|
15
|
+
else
|
16
|
+
raise exception
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def authorize_operation( result = nil, error_message = nil )
|
22
|
+
result = yield if block_given?
|
23
|
+
|
24
|
+
if result.is_a?( Array ) && result.first.is_a?( Unimatrix::ForbiddenError )
|
25
|
+
raise Unimatrix::AuthorizationError, error_message
|
26
|
+
end
|
27
|
+
|
28
|
+
result
|
29
|
+
end
|
30
|
+
|
31
|
+
protected; def token
|
32
|
+
@authorization_token ||= begin
|
33
|
+
Unimatrix::Authorization::ClientCredentialsGrant.new(
|
34
|
+
client_id: ENV[ 'KEYMAKER_CLIENT' ],
|
35
|
+
client_secret: ENV[ 'KEYMAKER_SECRET' ]
|
36
|
+
).request_token
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected; def token!
|
41
|
+
@authorization_token = nil
|
42
|
+
token
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -12,6 +12,7 @@ module Boxxspring
|
|
12
12
|
|
13
13
|
include Logging
|
14
14
|
include Metrics
|
15
|
+
include Authorization
|
15
16
|
|
16
17
|
#------------------------------------------------------------------------
|
17
18
|
# class attributes
|
@@ -54,7 +55,9 @@ module Boxxspring
|
|
54
55
|
queue_name = self.queue_name ||
|
55
56
|
self.name.underscore.gsub( /[\/]/, '-' ).
|
56
57
|
gsub( /_worker\Z/, '' )
|
57
|
-
self.environment + '-' + queue_name
|
58
|
+
full_name = self.environment + '-' + queue_name
|
59
|
+
|
60
|
+
ENV[ 'PRIORITY' ] ? ( full_name + '_priority' ) : full_name
|
58
61
|
end
|
59
62
|
|
60
63
|
end
|
@@ -63,8 +66,8 @@ module Boxxspring
|
|
63
66
|
# operations
|
64
67
|
|
65
68
|
def process
|
66
|
-
metric_defaults dimensions: { worker_name: self.class.name,
|
67
|
-
environment: environment } do
|
69
|
+
metric_defaults dimensions: { worker_name: self.class.name,
|
70
|
+
environment: environment } do
|
68
71
|
|
69
72
|
messages = self.receive_messages() || []
|
70
73
|
messages.each do | message |
|
@@ -73,14 +76,14 @@ module Boxxspring
|
|
73
76
|
|
74
77
|
if payload.present?
|
75
78
|
begin
|
76
|
-
metric :messages do
|
79
|
+
metric :messages do
|
77
80
|
result = self.process_payload( payload )
|
78
|
-
|
81
|
+
|
79
82
|
# note: if an exception is raised the message will be deleted
|
80
83
|
self.delete_message( message ) unless result == false
|
81
84
|
end
|
82
85
|
rescue StandardError => error
|
83
|
-
metric :errors
|
86
|
+
metric :errors
|
84
87
|
|
85
88
|
self.logger.error(
|
86
89
|
"The #{ self.human_name } failed to process the payload."
|
@@ -138,7 +141,7 @@ module Boxxspring
|
|
138
141
|
end
|
139
142
|
|
140
143
|
protected; def payload_from_message( message )
|
141
|
-
|
144
|
+
|
142
145
|
payload = message.body
|
143
146
|
|
144
147
|
if payload.present?
|
@@ -151,7 +154,7 @@ module Boxxspring
|
|
151
154
|
payload
|
152
155
|
end
|
153
156
|
else
|
154
|
-
logger.error( "The message lacks a payload." )
|
157
|
+
logger.error( "The message lacks a payload." )
|
155
158
|
logger.debug( message.inspect )
|
156
159
|
end
|
157
160
|
payload
|
@@ -38,7 +38,8 @@ module Boxxspring
|
|
38
38
|
secret_access_key: ENV[ 'AWS_SECRET_ACCESS_KEY' ]
|
39
39
|
},
|
40
40
|
group_name,
|
41
|
-
worker_name
|
41
|
+
worker_name,
|
42
|
+
region: ENV[ 'AWS_REGION' ]
|
42
43
|
)
|
43
44
|
|
44
45
|
end
|
@@ -77,7 +78,7 @@ module Boxxspring
|
|
77
78
|
log_local = ENV[ 'LOG_LOCAL' ] || 'false'
|
78
79
|
( log_local.to_s =~ /^true$/i ) == 0
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
require 'thread'
|
2
2
|
|
3
3
|
module Boxxspring
|
4
|
-
|
4
|
+
|
5
5
|
module Worker
|
6
|
-
|
6
|
+
|
7
7
|
module Metrics
|
8
|
-
|
9
|
-
METRICS_MUTEX = Mutex.new
|
10
|
-
METRICS_CLIENT = Aws::CloudWatch::Client.new
|
11
|
-
METRICS_UPLOAD_INTERVAL =
|
12
|
-
|
8
|
+
|
9
|
+
METRICS_MUTEX = Mutex.new
|
10
|
+
METRICS_CLIENT = Aws::CloudWatch::Client.new
|
11
|
+
METRICS_UPLOAD_INTERVAL = 0.5
|
12
|
+
|
13
13
|
def initialize( *arguments )
|
14
14
|
super
|
15
15
|
|
@@ -22,35 +22,40 @@ module Boxxspring
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def upload_metrics
|
25
|
-
loop do
|
25
|
+
loop do
|
26
26
|
unless @metrics.empty?
|
27
27
|
begin
|
28
|
-
metrics_payload = nil
|
29
|
-
|
28
|
+
metrics_payload = nil
|
29
|
+
|
30
30
|
METRICS_MUTEX.synchronize do
|
31
|
-
|
32
|
-
|
31
|
+
if @metrics.count > 20
|
32
|
+
logger.info( "Metrics queue has #{ @metrics.count } metrics" )
|
33
|
+
end
|
34
|
+
|
35
|
+
metrics_payload = @metrics.shift(20)
|
33
36
|
end
|
34
|
-
|
37
|
+
|
35
38
|
METRICS_CLIENT.put_metric_data( {
|
36
39
|
namespace: 'Unimatrix/Worker',
|
37
40
|
metric_data: metrics_payload
|
38
41
|
} )
|
39
42
|
|
40
|
-
rescue
|
41
|
-
logger.error(
|
43
|
+
rescue => error
|
44
|
+
logger.error(
|
42
45
|
"An error has occured when making a request to the AWS " +
|
43
|
-
"Cloudwatch endpoint 'put_metric_data'."
|
46
|
+
"Cloudwatch endpoint 'put_metric_data'. - Error message: " +
|
47
|
+
"#{ error.message }"
|
44
48
|
)
|
45
49
|
end
|
46
50
|
|
47
|
-
sleep METRICS_UPLOAD_INTERVAL
|
48
51
|
end
|
52
|
+
|
53
|
+
sleep METRICS_UPLOAD_INTERVAL
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
57
|
def metric_defaults( defaults = {} )
|
53
|
-
previous_defaults = @metric_defaults.last
|
58
|
+
previous_defaults = @metric_defaults.last
|
54
59
|
@metric_defaults.push( previous_defaults.merge( defaults ) )
|
55
60
|
|
56
61
|
yield
|
@@ -61,7 +66,7 @@ module Boxxspring
|
|
61
66
|
def metric ( *arguments )
|
62
67
|
arguments = [ arguments ] unless arguments.first.is_a? Array
|
63
68
|
computers = arguments.map do | metric |
|
64
|
-
parsed_metric = parse_metric( metric )
|
69
|
+
parsed_metric = parse_metric( metric )
|
65
70
|
|
66
71
|
computer_class =
|
67
72
|
"#{ parsed_metric[ :unit ].to_s.capitalize }MetricComputer".constantize
|
@@ -75,10 +80,10 @@ module Boxxspring
|
|
75
80
|
end
|
76
81
|
|
77
82
|
METRICS_MUTEX.synchronize do
|
78
|
-
@metrics = @metrics.concat(
|
79
|
-
computers.map( &:to_json ).delete_if { | json | json.blank? }
|
80
|
-
)
|
81
|
-
end
|
83
|
+
@metrics = @metrics.concat(
|
84
|
+
computers.map( &:to_json ).delete_if { | json | json.blank? }
|
85
|
+
)
|
86
|
+
end
|
82
87
|
|
83
88
|
end
|
84
89
|
|
@@ -14,10 +14,10 @@ module Boxxspring
|
|
14
14
|
# operations
|
15
15
|
|
16
16
|
protected; def process_task( task )
|
17
|
-
if self.class.processor.present?
|
17
|
+
if self.class.processor.present?
|
18
18
|
self.class.processor.call( task )
|
19
19
|
else
|
20
|
-
raise RuntimeError.new(
|
20
|
+
raise RuntimeError.new(
|
21
21
|
"The #{ self.human_name } lacks a task processor"
|
22
22
|
)
|
23
23
|
end
|
@@ -28,50 +28,46 @@ module Boxxspring
|
|
28
28
|
|
29
29
|
protected; def process_payload( payload )
|
30
30
|
result = true
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
if
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
task_state = 'failed'
|
59
|
-
task_message = "Task #{ task.id } processing has failed."
|
60
|
-
end
|
61
|
-
task = task_write_state( task, task_state, task_message )
|
62
|
-
self.logger.error( error.message )
|
63
|
-
self.logger.info( error.backtrace.join( "\n" ) )
|
64
|
-
raise error if error.is_a?( SignalException )
|
65
|
-
end
|
31
|
+
task = payload[ 'tasks' ].first
|
32
|
+
|
33
|
+
task_type_name = self.human_name.split( " " )
|
34
|
+
task_type_name.pop
|
35
|
+
task_type_name = task_type_name.join( "_" ) + "_task"
|
36
|
+
|
37
|
+
if task.present?
|
38
|
+
task_uuid = task[ 'uuid' ]
|
39
|
+
if task_type_name == payload[ '$this' ][ 'type_name' ]
|
40
|
+
task = Unimatrix::Activist::Task.new( task )
|
41
|
+
|
42
|
+
if task.is_a?( Unimatrix::Activist::Task )
|
43
|
+
self.logger.info(
|
44
|
+
"Task #{ task.uuid } processing has started."
|
45
|
+
)
|
46
|
+
begin
|
47
|
+
result = self.process_task( task )
|
48
|
+
message = "Task #{ task.uuid } processing has ended"
|
49
|
+
message += " and the message was retained." if result == false
|
50
|
+
self.logger.info( message )
|
51
|
+
rescue SignalException, StandardError => error
|
52
|
+
if error.is_a?( SignalException )
|
53
|
+
task_state = 'idle'
|
54
|
+
task_message = "Task #{ task.uuid } has restarted."
|
55
|
+
else
|
56
|
+
task_state = 'failed'
|
57
|
+
task_message = "Task #{ task.uuid } processing has failed."
|
66
58
|
end
|
67
|
-
|
68
|
-
self.logger.error(
|
69
|
-
|
70
|
-
|
71
|
-
"The #{self.human_name} is unable to retrieve the " +
|
72
|
-
"task with the id #{task_id}. #{task.inspect}"
|
73
|
-
)
|
59
|
+
task = task_write_state( task, task_state, task_message )
|
60
|
+
self.logger.error( error.message )
|
61
|
+
self.logger.info( error.backtrace.join( "\n" ) )
|
62
|
+
raise error if error.is_a?( SignalException )
|
74
63
|
end
|
64
|
+
elsif task.is_a?( Array ) && task.first.respond_to?( :message )
|
65
|
+
self.logger.error( task.first.message )
|
66
|
+
else
|
67
|
+
self.logger.error(
|
68
|
+
"The #{self.human_name} is unable to retrieve the " +
|
69
|
+
"task with the id #{task.uuid}. #{task.inspect}"
|
70
|
+
)
|
75
71
|
end
|
76
72
|
end
|
77
73
|
end
|
@@ -79,17 +75,19 @@ module Boxxspring
|
|
79
75
|
result
|
80
76
|
end
|
81
77
|
|
82
|
-
protected; def task_read(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
).read
|
78
|
+
protected; def task_read( task )
|
79
|
+
authorize_operation do
|
80
|
+
self.unimatrix_operation(
|
81
|
+
"/realms/#{ task.realm_uuid }/tasks/#{ task.uuid }"
|
82
|
+
).read
|
83
|
+
end
|
89
84
|
end
|
90
85
|
|
91
86
|
protected; def task_write( task )
|
92
|
-
|
87
|
+
authorize_operation do
|
88
|
+
self.unimatrix_operation( "/realms/#{ task.realm_uuid }/tasks" ).
|
89
|
+
write( 'tasks', task )
|
90
|
+
end
|
93
91
|
end
|
94
92
|
|
95
93
|
protected; def task_write_state( task, state, message )
|
@@ -100,37 +98,13 @@ module Boxxspring
|
|
100
98
|
self.task_write( task )
|
101
99
|
end
|
102
100
|
|
103
|
-
protected; def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
)
|
108
|
-
end
|
109
|
-
|
110
|
-
protected; def task_property_read( task, include = nil )
|
111
|
-
operation = Boxxspring::Operation.new(
|
112
|
-
"/properties/#{ task.property_id }",
|
113
|
-
Worker.configuration.api_credentials.to_hash
|
101
|
+
protected; def unimatrix_operation( endpoint, args = {} )
|
102
|
+
Unimatrix::Operation.new(
|
103
|
+
endpoint,
|
104
|
+
args.merge( { access_token: token } )
|
114
105
|
)
|
115
|
-
operation = operation.include( include ) \
|
116
|
-
unless ( include.blank? )
|
117
|
-
operation.read
|
118
|
-
end
|
119
|
-
|
120
|
-
protected; def task_delegate( queue_name, task )
|
121
|
-
serializer = Boxxspring::Serializer.new( task )
|
122
|
-
payload = serializer.serialize( 'tasks' )
|
123
|
-
payload.merge!( {
|
124
|
-
'$this' => {
|
125
|
-
'type_name' => 'tasks',
|
126
|
-
'unlimited_count' => 1
|
127
|
-
}
|
128
|
-
} )
|
129
|
-
self.delegate_payload( queue_name, payload )
|
130
106
|
end
|
131
107
|
|
132
108
|
end
|
133
|
-
|
134
109
|
end
|
135
|
-
|
136
110
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boxxspring-workers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kristoph Cichocki-Romanov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: unimatrix
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: aws-sdk
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -126,8 +140,10 @@ files:
|
|
126
140
|
- lib/boxxspring/synchronization/orchestrator.rb
|
127
141
|
- lib/boxxspring/synchronization/variable.rb
|
128
142
|
- lib/boxxspring/worker.rb
|
143
|
+
- lib/boxxspring/worker/authorization.rb
|
129
144
|
- lib/boxxspring/worker/base.rb
|
130
145
|
- lib/boxxspring/worker/configuration.rb
|
146
|
+
- lib/boxxspring/worker/error.rb
|
131
147
|
- lib/boxxspring/worker/logging.rb
|
132
148
|
- lib/boxxspring/worker/metrics.rb
|
133
149
|
- lib/boxxspring/worker/metrics/count_metric_computer.rb
|
@@ -157,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
173
|
version: '0'
|
158
174
|
requirements: []
|
159
175
|
rubyforge_project:
|
160
|
-
rubygems_version: 2.
|
176
|
+
rubygems_version: 2.7.7
|
161
177
|
signing_key:
|
162
178
|
specification_version: 4
|
163
179
|
summary: Bedrocket Media Ventrures Boxxspring Worker framework.
|