right_support 2.12.1 → 2.13.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/right_support/data/hash_tools.rb +76 -0
- data/lib/right_support/net/request_balancer.rb +11 -1
- data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +23 -3
- data/lib/right_support/rack.rb +6 -7
- data/lib/right_support/rack/request_logger.rb +8 -31
- data/lib/right_support/rack/request_tracker.rb +59 -10
- data/lib/right_support/rack/shared_environment.rb +112 -0
- data/right_support.gemspec +4 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88f99381f01a8163458dfbb3428605aa10504ecf
|
4
|
+
data.tar.gz: c15fde263a3abf66adf8a665b7aabb27a530a89a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c54a1945a13c506c38e2cfc337db07c9d68c2691fc2e501dc68ec16f1fa95670797927f384dd6bb2635c6b01d39b27c5a66994e8ffc910dded8ff505010c15e6
|
7
|
+
data.tar.gz: 08b6bac68cc7b5ebbb12a319fac566b904ef993f452956ac39c9a8371961c2c0fabe1849f407a5681560f627fe80e2c1b588089653db8ee9ef1a3a4e68fe287b
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.13.3
|
@@ -486,5 +486,81 @@ module RightSupport::Data
|
|
486
486
|
raise NoJson, "JSON is unavailable"
|
487
487
|
end
|
488
488
|
end
|
489
|
+
|
490
|
+
# provides a canonical representation of a header key that is acceptable to
|
491
|
+
# Rack, etc. the web standard for canonical header keys is all lowercase
|
492
|
+
# except with the first character capitalized at the start and after each
|
493
|
+
# dash. underscores are converted to dash characters.
|
494
|
+
def self.canonicalize_header_key(key)
|
495
|
+
key.to_s.downcase.gsub('_', '-').gsub(/(^|-)(.)/) { $1 + $2.upcase }
|
496
|
+
end
|
497
|
+
|
498
|
+
# @return [String] header value by canonical key name, if present.
|
499
|
+
def self.header_value_get(headers, key)
|
500
|
+
return nil unless headers
|
501
|
+
canonical_key = canonicalize_header_key(key)
|
502
|
+
value = nil
|
503
|
+
headers.each do |k, v|
|
504
|
+
if canonicalize_header_key(k) == canonical_key
|
505
|
+
value = v
|
506
|
+
break
|
507
|
+
end
|
508
|
+
end
|
509
|
+
value
|
510
|
+
end
|
511
|
+
|
512
|
+
# safely sets a header value by first locating any existing key by canonical
|
513
|
+
# search. if you know that the header hash is already canonical then you can
|
514
|
+
# alternatively set by using the canonicalized key.
|
515
|
+
#
|
516
|
+
# @param [Hash] headers to modify
|
517
|
+
# @param [String] key for header
|
518
|
+
# @param [String] value for header
|
519
|
+
#
|
520
|
+
# @return [Hash] updated headers
|
521
|
+
def self.header_value_set(headers, key, value)
|
522
|
+
headers ||= {}
|
523
|
+
canonical_key = canonicalize_header_key(key)
|
524
|
+
headers.each do |k, v|
|
525
|
+
if canonicalize_header_key(k) == canonical_key
|
526
|
+
key = k
|
527
|
+
break
|
528
|
+
end
|
529
|
+
end
|
530
|
+
headers[key] = value
|
531
|
+
headers
|
532
|
+
end
|
533
|
+
|
534
|
+
# duplicates the given headers hash after canonicalizing header keys.
|
535
|
+
#
|
536
|
+
# @param [Hash] headers to canonicalize
|
537
|
+
#
|
538
|
+
# @return [Hash] canonicalized headers
|
539
|
+
def self.canonicalize_headers(headers)
|
540
|
+
headers.inject({}) do |h, (k, v)|
|
541
|
+
h[canonicalize_header_key(k)] = v
|
542
|
+
h
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
# merges source headers hash into the duplicated target headers canonically.
|
547
|
+
# also supports removal of a target header when the source value is nil.
|
548
|
+
#
|
549
|
+
# @param [Hash] target to merge to
|
550
|
+
# @param [String] source to merge from
|
551
|
+
# @return [Hash] merged headers
|
552
|
+
def self.merge_headers(target, source)
|
553
|
+
target = canonicalize_headers(target)
|
554
|
+
(source || {}).each do |k, v|
|
555
|
+
canonical_key = canonicalize_header_key(k)
|
556
|
+
if v.nil?
|
557
|
+
target.delete(canonical_key)
|
558
|
+
else
|
559
|
+
target[canonical_key] = v
|
560
|
+
end
|
561
|
+
end
|
562
|
+
target
|
563
|
+
end
|
564
|
+
|
489
565
|
end
|
490
566
|
end
|
@@ -403,7 +403,17 @@ module RightSupport::Net
|
|
403
403
|
stats = get_stats
|
404
404
|
exceptions.each_pair do |endpoint, list|
|
405
405
|
summary = []
|
406
|
-
list.each
|
406
|
+
list.each do |e|
|
407
|
+
if e.message.to_s.empty?
|
408
|
+
summary << e.class.name
|
409
|
+
else
|
410
|
+
message_top = e.message.to_s.lines.first.chomp
|
411
|
+
if message_top.length > 128
|
412
|
+
message_top = message_top[0, 124] + ' ...'
|
413
|
+
end
|
414
|
+
summary << "#{e.class.name}: #{message_top}"
|
415
|
+
end
|
416
|
+
end
|
407
417
|
health = stats[endpoint] if stats[endpoint] != 'n/a'
|
408
418
|
if hostname = lookup_hostname(endpoint)
|
409
419
|
msg << "'#{hostname}' (#{endpoint}#{", "+health if health}) => [#{summary.uniq.join(', ')}]"
|
@@ -99,7 +99,6 @@ class RightSupport::Notifier::Utility::BacktraceDecoder
|
|
99
99
|
frames = []
|
100
100
|
trace ||= []
|
101
101
|
trace = trace[@backtrace_offset..-1] if @backtrace_offset > 0
|
102
|
-
gems_finder = '/gems/'
|
103
102
|
seen_root_path = false
|
104
103
|
trace.each do |t|
|
105
104
|
has_root_path = false
|
@@ -134,8 +133,29 @@ class RightSupport::Notifier::Utility::BacktraceDecoder
|
|
134
133
|
# rubygems or '/vendor/bundle/.../gems/' prefixes are only noise that
|
135
134
|
# makes the trace harder to read for a human. '/gems/' may also appear
|
136
135
|
# more than once so use the last found.
|
137
|
-
|
138
|
-
|
136
|
+
#
|
137
|
+
# also note that vendored gitted gems and their binstubs can appear
|
138
|
+
# directly under the '<app root>/vendor/bundle|cache/' directory and
|
139
|
+
# so are not explicitly under a '/gems/' directory.
|
140
|
+
founder = nil
|
141
|
+
founder_offset = nil
|
142
|
+
%w(
|
143
|
+
/gems/
|
144
|
+
/vendor/cache/
|
145
|
+
/vendor/bundle/
|
146
|
+
).each do |finder|
|
147
|
+
if founder_offset = file.rindex(finder)
|
148
|
+
founder = finder
|
149
|
+
break
|
150
|
+
end
|
151
|
+
end
|
152
|
+
if founder
|
153
|
+
file = file[founder_offset + founder.length..-1]
|
154
|
+
|
155
|
+
# note that vendored gems are also technically on the 'root path'
|
156
|
+
# but we do not want to include them in the 'seen root path'
|
157
|
+
# logic because we want to see the trace back to real app code.
|
158
|
+
has_root_path = false
|
139
159
|
end
|
140
160
|
end
|
141
161
|
else
|
data/lib/right_support/rack.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2011 RightScale Inc
|
2
|
+
# Copyright (c) 2011-2016 RightScale Inc
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -25,11 +25,10 @@ module RightSupport
|
|
25
25
|
# A namespace for Rack middleware and other enhancements.
|
26
26
|
#
|
27
27
|
module Rack
|
28
|
-
|
28
|
+
autoload :LogSetter, 'right_support/rack/log_setter'
|
29
|
+
autoload :RequestLogger, 'right_support/rack/request_logger'
|
30
|
+
autoload :RequestTracker, 'right_support/rack/request_tracker'
|
31
|
+
autoload :Runtime, 'right_support/rack/runtime'
|
32
|
+
autoload :SharedEnvironment, 'right_support/rack/shared_environment'
|
29
33
|
end
|
30
34
|
end
|
31
|
-
|
32
|
-
require 'right_support/rack/log_setter'
|
33
|
-
require 'right_support/rack/request_logger'
|
34
|
-
require 'right_support/rack/request_tracker'
|
35
|
-
require 'right_support/rack/runtime'
|
@@ -185,44 +185,21 @@ module RightSupport::Rack
|
|
185
185
|
raise
|
186
186
|
end
|
187
187
|
|
188
|
-
#
|
189
|
-
# Rack, etc.
|
188
|
+
# @deprecated in favor of RightSupport::Data::HashTools.canonicalize_header_key
|
190
189
|
def self.canonicalize_header_key(key)
|
190
|
+
# the legacy implementation is train-case but HashTools uses the more
|
191
|
+
# commonly accepted Canonical-Key style (preferred by golang, etc).
|
191
192
|
key.downcase.gsub('_', '-')
|
192
193
|
end
|
193
194
|
|
194
|
-
# @
|
195
|
+
# @deprecated in favor of RightSupport::Data::HashTools.header_value_get
|
195
196
|
def self.header_value_get(headers, key)
|
196
|
-
return
|
197
|
-
key = canonicalize_header_key(key)
|
198
|
-
value = nil
|
199
|
-
headers.each do |k, v|
|
200
|
-
if canonicalize_header_key(k) == key
|
201
|
-
value = v
|
202
|
-
break
|
203
|
-
end
|
204
|
-
end
|
205
|
-
value
|
197
|
+
return ::RightSupport::Data::HashTools.header_value_get(headers, key)
|
206
198
|
end
|
207
199
|
|
208
|
-
#
|
209
|
-
# search.
|
210
|
-
#
|
211
|
-
# @param [Hash] headers to modify
|
212
|
-
# @param [String] key for header
|
213
|
-
# @param [String] value for header
|
214
|
-
# @return [Hash] updated headers
|
200
|
+
# @deprecated in favor of RightSupport::Data::HashTools.header_value_set
|
215
201
|
def self.header_value_set(headers, key, value)
|
216
|
-
headers
|
217
|
-
key = canonicalize_header_key(key)
|
218
|
-
headers.each do |k, v|
|
219
|
-
if canonicalize_header_key(k) == key
|
220
|
-
key = k
|
221
|
-
break
|
222
|
-
end
|
223
|
-
end
|
224
|
-
headers[key] = value
|
225
|
-
headers
|
202
|
+
return ::RightSupport::Data::HashTools.header_value_set(headers, key, value)
|
226
203
|
end
|
227
204
|
|
228
205
|
# Formats a concise error message with limited backtrace, etc.
|
@@ -342,7 +319,7 @@ module RightSupport::Rack
|
|
342
319
|
# @return [TrueClass] always true
|
343
320
|
def log_request_end(logger, env, status, headers, body, began_at)
|
344
321
|
duration = (Time.now - began_at) * 1000
|
345
|
-
unless content_length =
|
322
|
+
unless content_length = ::RightSupport::Data::HashTools.header_value_get(headers, 'Content-Length')
|
346
323
|
case body
|
347
324
|
when Array
|
348
325
|
content_length = body.reduce(0) {|accum, e| accum += e.bytesize}
|
@@ -49,6 +49,13 @@ module RightSupport::Rack
|
|
49
49
|
# value to finding and replacing with _id in all cases.
|
50
50
|
REQUEST_UUID_ENV_NAME = 'rack.request_uuid'.freeze
|
51
51
|
|
52
|
+
# records count of additional API calls made by an application while
|
53
|
+
# handling a request, etc. this is useful for generating an incremental
|
54
|
+
# request [UU]ID to be forwarded to other services for additional API calls.
|
55
|
+
#
|
56
|
+
# @see RightSupport::Rack::RequestTracker.next_request_uuid
|
57
|
+
API_CALL_COUNTER_ENV_KEY = 'request_tracker.api_call_counter'
|
58
|
+
|
52
59
|
# @deprecated do not send the lineage header as support may go away.
|
53
60
|
REQUEST_LINEAGE_UUID_HEADER = 'HTTP_X_REQUEST_LINEAGE_UUID'.freeze
|
54
61
|
|
@@ -118,23 +125,57 @@ module RightSupport::Rack
|
|
118
125
|
end
|
119
126
|
|
120
127
|
# copies the request [UU]ID from the request environment to the given hash,
|
121
|
-
# if present.
|
122
|
-
# was not present, etc.)
|
128
|
+
# if present.
|
123
129
|
#
|
124
|
-
# @param [Hash] from_env as source
|
130
|
+
# @param [Hash] from_env as source hash
|
125
131
|
# @param [Hash] to_headers as target
|
132
|
+
# @param [Hash] options
|
133
|
+
# @option options [Proc|Method] :generator as callback to generate a new
|
134
|
+
# request uuid when not present or nil
|
135
|
+
# @option options [Proc|Method] :modifier as callback to modify request uuid
|
136
|
+
# before it is finally inserted in headers or nil. this can be useful for
|
137
|
+
# appending a counter for each new API call made by a request handler, etc.
|
138
|
+
# only called if identifier was retrieved from the environment hash because
|
139
|
+
# an explicity-set (or generated) ID value is used without modification.
|
140
|
+
# @option options [TrueClass|FalseClass] :return_request_uuid as true to
|
141
|
+
# return a tuple of [to_headers, request_uuid] instead. false to only
|
142
|
+
# return updated to_headers (default).
|
126
143
|
#
|
127
|
-
# @return [Hash] updated
|
128
|
-
|
144
|
+
# @return [Hash|Array] updated to_headers (default) or tuple of
|
145
|
+
# [to_headers, request_uuid]. see :return_request_uuid option.
|
146
|
+
def self.copy_request_uuid(from_env, to_headers, options = {})
|
147
|
+
options = {
|
148
|
+
generator: nil,
|
149
|
+
modifier: nil,
|
150
|
+
return_request_uuid: false
|
151
|
+
}.merge(options)
|
152
|
+
from_env ||= {}
|
129
153
|
to_headers ||= {}
|
130
|
-
|
154
|
+
|
155
|
+
# keep existing ID value, if any.
|
156
|
+
request_uuid = ::RightSupport::Data::HashTools.header_value_get(
|
157
|
+
to_headers,
|
158
|
+
REQUEST_ID_HEADER)
|
159
|
+
unless request_uuid
|
160
|
+
# attempt to find ID key in environment hash.
|
131
161
|
if request_uuid = from_env[REQUEST_UUID_ENV_NAME]
|
132
|
-
#
|
133
|
-
|
134
|
-
|
135
|
-
|
162
|
+
# use modifier, if any.
|
163
|
+
if modifier = options[:modifier]
|
164
|
+
request_uuid = modifier.call(request_uuid)
|
165
|
+
end
|
166
|
+
else
|
167
|
+
# use generator, if any.
|
168
|
+
if generator = options[:generator]
|
169
|
+
request_uuid = generator.call
|
170
|
+
end
|
136
171
|
end
|
172
|
+
|
173
|
+
# note that we will always forward the _ID header as the standard.
|
174
|
+
# none of the RS code ever actually accepted the _UUID header so that
|
175
|
+
# is a non-issue.
|
176
|
+
to_headers[REQUEST_ID_HEADER] = request_uuid if request_uuid
|
137
177
|
end
|
178
|
+
return [to_headers, request_uuid] if options[:return_request_uuid]
|
138
179
|
to_headers
|
139
180
|
end
|
140
181
|
|
@@ -146,5 +187,13 @@ module RightSupport::Rack
|
|
146
187
|
Generator.generate
|
147
188
|
end
|
148
189
|
|
190
|
+
# @return [String] next request [UU]ID
|
191
|
+
def self.next_request_uuid(env, base_request_uuid = nil)
|
192
|
+
base_request_uuid ||= env[REQUEST_UUID_ENV_NAME] || 'missing'
|
193
|
+
env[API_CALL_COUNTER_ENV_KEY] ||= 0
|
194
|
+
n = env[API_CALL_COUNTER_ENV_KEY] += 1
|
195
|
+
"#{base_request_uuid}_#{n}"
|
196
|
+
end
|
197
|
+
|
149
198
|
end # RequestTracker
|
150
199
|
end # RightSupport::Rack
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2016 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
module RightSupport::Rack
|
24
|
+
|
25
|
+
# provides shared access to the Rack request environment hash for any method
|
26
|
+
# executing on the request thread without needing to pass the hash explicitly.
|
27
|
+
# explicit parameter passing is preferred when writing new code, of course,
|
28
|
+
# but it can be difficult to update old code with new parameters going several
|
29
|
+
# layers deep. this middleware attempts to simplify those changes.
|
30
|
+
#
|
31
|
+
# note that only the request thread receives the environment hash so any
|
32
|
+
# threads spawned by the request thread will need to explicitly reference any
|
33
|
+
# needed hash values and/or the entire hash using the accessors.
|
34
|
+
class SharedEnvironment
|
35
|
+
|
36
|
+
# the symbol that represents the Rack request environment hash in TLS.
|
37
|
+
ENVIRONMENT_HASH_SYMBOL = :rack_request_environment_hash
|
38
|
+
|
39
|
+
# @param [Object] app to call
|
40
|
+
# @param [Hash] options
|
41
|
+
# @option options [TrueClass|FalseClass] :fiber_local as false to set the
|
42
|
+
# environment hash visible to all fibers of the current thread (default) or
|
43
|
+
# true to set a fiber-local environment hash. if your app does not attempt
|
44
|
+
# to use fibers then either will work as every thread has a root fiber.
|
45
|
+
# if your app creates fibers while handling requests then the default of
|
46
|
+
# thread-local is probably best because the environment hash is shared with
|
47
|
+
# all fibers. keep in mind that the thread and its root fiber keep distinct
|
48
|
+
# hashes so you must reference one or the other.
|
49
|
+
def initialize(app, options = {})
|
50
|
+
options = {
|
51
|
+
fiber_local: false
|
52
|
+
}.merge(options)
|
53
|
+
@app = app
|
54
|
+
@fiber_local = !!options[:fiber_local]
|
55
|
+
end
|
56
|
+
|
57
|
+
def call(env)
|
58
|
+
# sanity check in case the application developer is unaware that the
|
59
|
+
# execution model is using fibers instead of threads, etc.
|
60
|
+
fail 'Environment hash is already set.' unless get_environment_hash.empty?
|
61
|
+
set_environment_hash(env)
|
62
|
+
return @app.call(env)
|
63
|
+
ensure
|
64
|
+
# only intended for use by the application; middleware already has env
|
65
|
+
# available on each call. reset to nil before falling back.
|
66
|
+
# also note that there is no such animal as thread_variable_delete, etc.
|
67
|
+
set_environment_hash(nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Hash] environment hash or empty
|
71
|
+
def get_environment_hash
|
72
|
+
return self.class.get_environment_hash(@fiber_local)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param [Hash] env as environment hash or nil or empty
|
76
|
+
#
|
77
|
+
# @return [TrueClass] always true
|
78
|
+
def set_environment_hash(env)
|
79
|
+
return self.class.set_environment_hash(env, @fiber_local)
|
80
|
+
end
|
81
|
+
|
82
|
+
# gets the environment hash for current thread or fiber.
|
83
|
+
#
|
84
|
+
# @return [Hash] environment hash or empty
|
85
|
+
def self.get_environment_hash(fiber_local = false)
|
86
|
+
current = ::Thread.current
|
87
|
+
if fiber_local
|
88
|
+
# note that in ruby 1.8 this would have referred to thread-local storage
|
89
|
+
# but in ruby 1.9+ it refers to fiber-local storage.
|
90
|
+
current[ENVIRONMENT_HASH_SYMBOL] || {}
|
91
|
+
else
|
92
|
+
# in ruby 1.9+ you must explicitly call for thread-local variables.
|
93
|
+
current.thread_variable_get(ENVIRONMENT_HASH_SYMBOL) || {}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# sets the environment hash for current thread or fiber.
|
98
|
+
#
|
99
|
+
# @param [Hash] env as environment hash or nil or empty
|
100
|
+
#
|
101
|
+
# @return [TrueClass] always true
|
102
|
+
def self.set_environment_hash(env, fiber_local = false)
|
103
|
+
current = ::Thread.current
|
104
|
+
if fiber_local
|
105
|
+
current[ENVIRONMENT_HASH_SYMBOL] = env
|
106
|
+
else
|
107
|
+
current.thread_variable_set(ENVIRONMENT_HASH_SYMBOL, env)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
data/right_support.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: right_support 2.
|
5
|
+
# stub: right_support 2.13.3 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "right_support"
|
9
|
-
s.version = "2.
|
9
|
+
s.version = "2.13.3"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Tony Spataro", "Sergey Sergyenko", "Ryan Williamson", "Lee Kirchhoff", "Alexey Karpik", "Scott Messier"]
|
14
|
-
s.date = "2016-
|
14
|
+
s.date = "2016-09-12"
|
15
15
|
s.description = "A toolkit of useful, reusable foundation code created by RightScale."
|
16
16
|
s.email = "support@rightscale.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -88,6 +88,7 @@ Gem::Specification.new do |s|
|
|
88
88
|
"lib/right_support/rack/request_logger.rb",
|
89
89
|
"lib/right_support/rack/request_tracker.rb",
|
90
90
|
"lib/right_support/rack/runtime.rb",
|
91
|
+
"lib/right_support/rack/shared_environment.rb",
|
91
92
|
"lib/right_support/ruby.rb",
|
92
93
|
"lib/right_support/ruby/easy_singleton.rb",
|
93
94
|
"lib/right_support/ruby/object_extensions.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.13.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Spataro
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2016-
|
16
|
+
date: 2016-09-13 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: rake
|
@@ -162,6 +162,7 @@ files:
|
|
162
162
|
- lib/right_support/rack/request_logger.rb
|
163
163
|
- lib/right_support/rack/request_tracker.rb
|
164
164
|
- lib/right_support/rack/runtime.rb
|
165
|
+
- lib/right_support/rack/shared_environment.rb
|
165
166
|
- lib/right_support/ruby.rb
|
166
167
|
- lib/right_support/ruby/easy_singleton.rb
|
167
168
|
- lib/right_support/ruby/object_extensions.rb
|