right_support 2.12.1 → 2.13.3
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/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
|