right_support 2.8.26 → 2.8.27
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.
- data/VERSION +1 -1
- data/lib/right_support/stats/activity.rb +31 -12
- data/lib/right_support/stats/helpers.rb +3 -3
- data/right_support.gemspec +3 -3
- data/spec/stats/activity_spec.rb +53 -16
- data/spec/stats/helpers_spec.rb +3 -3
- metadata +13 -8
- checksums.yaml +0 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.8.
|
1
|
+
2.8.27
|
@@ -56,7 +56,7 @@ module RightSupport::Stats
|
|
56
56
|
def reset
|
57
57
|
@interval = 0.0
|
58
58
|
@last_start_time = Time.now
|
59
|
-
@
|
59
|
+
@avg_latency = nil
|
60
60
|
@total = 0
|
61
61
|
@count_per_type = {}
|
62
62
|
@last_type = nil
|
@@ -89,22 +89,22 @@ module RightSupport::Stats
|
|
89
89
|
now
|
90
90
|
end
|
91
91
|
|
92
|
-
# Mark the finish of an activity and update the average
|
92
|
+
# Mark the finish of an activity and update the average latency
|
93
93
|
#
|
94
94
|
# @param start_time [Time] Time when activity started, defaults to last time update was called
|
95
95
|
# @param id [String] Unique identifier associated with this activity
|
96
96
|
#
|
97
|
-
# @return [Float] Activity
|
97
|
+
# @return [Float] Activity latency in seconds
|
98
98
|
def finish(start_time = nil, id = nil)
|
99
99
|
now = Time.now
|
100
100
|
start_time ||= @last_start_time
|
101
|
-
|
102
|
-
@
|
101
|
+
latency = now - start_time
|
102
|
+
@avg_latency = average(@avg_latency || 0.0, latency)
|
103
103
|
@last_id = 0 if id && id == @last_id
|
104
|
-
|
104
|
+
latency
|
105
105
|
end
|
106
106
|
|
107
|
-
# Update activity and measure its
|
107
|
+
# Update activity and measure its latency
|
108
108
|
#
|
109
109
|
# @param type [String, Symbol] Type of activity, with anything that is not a symbol, true, or false
|
110
110
|
# automatically converted to a String and truncated to MAX_TYPE_SIZE characters; defaults to nil
|
@@ -134,14 +134,17 @@ module RightSupport::Stats
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
# Get average
|
137
|
+
# Get average latency for performing an activity
|
138
138
|
#
|
139
|
-
# @return [Float, NilClass] Average
|
139
|
+
# @return [Float, NilClass] Average latency in seconds of activity weighted
|
140
140
|
# toward past activity, or nil if total is 0
|
141
|
-
def
|
142
|
-
@
|
141
|
+
def avg_latency
|
142
|
+
@avg_latency
|
143
143
|
end
|
144
144
|
|
145
|
+
# avg_duration is deprecated but still supported
|
146
|
+
alias :avg_duration :avg_latency
|
147
|
+
|
145
148
|
# Get stats about last activity
|
146
149
|
#
|
147
150
|
# @return [Hash, NilClass] Information about last activity, or nil if the total is 0
|
@@ -170,7 +173,7 @@ module RightSupport::Stats
|
|
170
173
|
end
|
171
174
|
end
|
172
175
|
|
173
|
-
# Get stat summary including all aspects of activity that were measured except
|
176
|
+
# Get stat summary including all aspects of activity that were measured except latency
|
174
177
|
#
|
175
178
|
# @return [Hash, NilClass] Information about activity, or nil if the total is 0
|
176
179
|
# "total" [Integer] Total activity count
|
@@ -180,6 +183,7 @@ module RightSupport::Stats
|
|
180
183
|
# "type" [String] Type of activity if tracking type, otherwise omitted
|
181
184
|
# "active" [Boolean] Whether activity still active if tracking whether active, otherwise omitted
|
182
185
|
# "rate" [Float] Recent average rate if measuring rate, otherwise omitted
|
186
|
+
# "latency" [Float] Recent average latency if measuring latency, otherwise omitted
|
183
187
|
def all
|
184
188
|
if @total > 0
|
185
189
|
result = if @count_per_type.empty?
|
@@ -189,6 +193,7 @@ module RightSupport::Stats
|
|
189
193
|
end
|
190
194
|
result.merge!("last" => last)
|
191
195
|
result.merge!("rate" => avg_rate) if @measure_rate
|
196
|
+
result.merge!("latency" => avg_latency) if @avg_latency
|
192
197
|
result
|
193
198
|
end
|
194
199
|
end
|
@@ -219,12 +224,15 @@ module RightSupport::Stats
|
|
219
224
|
# "type" [String] Type of activity if tracking type, otherwise omitted
|
220
225
|
# "active" [Boolean] Whether activity still active if tracking whether active, otherwise omitted
|
221
226
|
# "rate" [Float] Recent average rate if measuring rate, otherwise omitted
|
227
|
+
# "latency" [Float] Recent average latency if measuring latency, otherwise omitted
|
222
228
|
def self.all(stats)
|
223
229
|
if (total = stats.inject(0) { |t, s| t += s["total"] if s && s["total"]; t }) > 0
|
224
230
|
all = percentage(stats, total)
|
225
231
|
all["last"] = last(stats.map { |s| s["last"] if s })
|
226
232
|
rate = avg_rate(stats.map { |s| {"rate" => s["rate"], "total" => s["total"]} if s }, total)
|
227
233
|
all["rate"] = rate if rate
|
234
|
+
latency = avg_latency(stats.map { |s| {"latency" => s["latency"], "total" => s["total"]} if s }, total)
|
235
|
+
all["latency"] = latency if latency
|
228
236
|
all
|
229
237
|
end
|
230
238
|
end
|
@@ -267,6 +275,17 @@ module RightSupport::Stats
|
|
267
275
|
sum / total if sum
|
268
276
|
end
|
269
277
|
|
278
|
+
# Compute average latency from multiple average latency
|
279
|
+
#
|
280
|
+
# @param stats [Array] List of stats containing hash of "latency" and "total"
|
281
|
+
# @param total [Integer] Overall total
|
282
|
+
#
|
283
|
+
# @return [Fixnum, NilClass] Average latency or nil if no average latency data
|
284
|
+
def self.avg_latency(stats, total)
|
285
|
+
sum = stats.inject(nil) { |sum, stat| sum = (sum || 0.0) + (stat["latency"] * stat["total"]) if stat && stat["latency"]; sum }
|
286
|
+
sum / total if sum
|
287
|
+
end
|
288
|
+
|
270
289
|
# Determine last activity from multiple last activity stats
|
271
290
|
#
|
272
291
|
# @param stats [Array] Multiple last activity stats
|
@@ -420,7 +420,7 @@ module RightSupport
|
|
420
420
|
# "type"(String):: Type of activity if tracking type, otherwise omitted
|
421
421
|
# "active"(Boolean):: Whether activity still active if tracking whether active, otherwise omitted
|
422
422
|
# "rate" [Float] Recent average rate if measuring rate, otherwise omitted
|
423
|
-
# "
|
423
|
+
# "latency" [Float] Recent average latency of activity if tracking latency, otherwise omitted
|
424
424
|
#
|
425
425
|
# @return [String] Activity stats in displayable format without any line separators
|
426
426
|
def self.activity_str(value)
|
@@ -430,9 +430,9 @@ module RightSupport
|
|
430
430
|
str += "#{value['total']}"
|
431
431
|
str += ", last: #{last_activity_str(value['last'], single_item = true)}" if value["last"]
|
432
432
|
str += ", rate: #{enough_precision(value['rate'])}/sec" if value["rate"]
|
433
|
-
str += ",
|
433
|
+
str += ", latency: #{enough_precision(value['latency'])} sec" if value["latency"]
|
434
434
|
value.each do |name, data|
|
435
|
-
unless ["total", "percent", "last", "rate", "
|
435
|
+
unless ["total", "percent", "last", "rate", "latency"].include?(name)
|
436
436
|
str += ", #{name}: #{data.is_a?(String) ? data : data.inspect}"
|
437
437
|
end
|
438
438
|
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.8.
|
5
|
+
# stub: right_support 2.8.27 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "right_support"
|
9
|
-
s.version = "2.8.
|
9
|
+
s.version = "2.8.27"
|
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 = "2014-08-
|
14
|
+
s.date = "2014-08-08"
|
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 = [
|
data/spec/stats/activity_spec.rb
CHANGED
@@ -47,7 +47,7 @@ describe RightSupport::Stats::Activity do
|
|
47
47
|
it "initializes stats data" do
|
48
48
|
@stats.instance_variable_get(:@interval).should == 0.0
|
49
49
|
@stats.instance_variable_get(:@last_start_time).should == @now
|
50
|
-
@stats.instance_variable_get(:@
|
50
|
+
@stats.instance_variable_get(:@avg_latency).should be_nil
|
51
51
|
@stats.instance_variable_get(:@total).should == 0
|
52
52
|
@stats.instance_variable_get(:@count_per_type).should == {}
|
53
53
|
end
|
@@ -59,7 +59,7 @@ describe RightSupport::Stats::Activity do
|
|
59
59
|
@stats.update
|
60
60
|
@stats.instance_variable_get(:@interval).should == 1.0
|
61
61
|
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
62
|
-
@stats.instance_variable_get(:@
|
62
|
+
@stats.instance_variable_get(:@avg_latency).should be_nil
|
63
63
|
@stats.instance_variable_get(:@total).should == 1
|
64
64
|
@stats.instance_variable_get(:@count_per_type).should == {}
|
65
65
|
end
|
@@ -69,7 +69,7 @@ describe RightSupport::Stats::Activity do
|
|
69
69
|
@stats.update("test")
|
70
70
|
@stats.instance_variable_get(:@interval).should == 1.0
|
71
71
|
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
72
|
-
@stats.instance_variable_get(:@
|
72
|
+
@stats.instance_variable_get(:@avg_latency).should be_nil
|
73
73
|
@stats.instance_variable_get(:@total).should == 1
|
74
74
|
@stats.instance_variable_get(:@count_per_type).should == {"test" => 1}
|
75
75
|
end
|
@@ -106,7 +106,7 @@ describe RightSupport::Stats::Activity do
|
|
106
106
|
@stats.update
|
107
107
|
@stats.instance_variable_get(:@interval).should == 0.0
|
108
108
|
@stats.instance_variable_get(:@last_start_time).should == @now + 10
|
109
|
-
@stats.instance_variable_get(:@
|
109
|
+
@stats.instance_variable_get(:@avg_latency).should be_nil
|
110
110
|
@stats.instance_variable_get(:@total).should == 1
|
111
111
|
@stats.instance_variable_get(:@count_per_type).should == {}
|
112
112
|
end
|
@@ -118,24 +118,24 @@ describe RightSupport::Stats::Activity do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
context :finish do
|
121
|
-
it "updates
|
121
|
+
it "updates latency when finish using internal start time by default" do
|
122
122
|
flexmock(Time).should_receive(:now).and_return(1000010)
|
123
|
-
@stats.
|
123
|
+
@stats.avg_latency.should be_nil
|
124
124
|
@stats.finish
|
125
125
|
@stats.instance_variable_get(:@interval).should == 0.0
|
126
126
|
@stats.instance_variable_get(:@last_start_time).should == @now
|
127
|
-
@stats.instance_variable_get(:@
|
127
|
+
@stats.instance_variable_get(:@avg_latency).should == 1.0
|
128
128
|
@stats.instance_variable_get(:@total).should == 0
|
129
129
|
@stats.instance_variable_get(:@count_per_type).should == {}
|
130
130
|
end
|
131
131
|
|
132
|
-
it "updates
|
132
|
+
it "updates latency when finish using specified start time" do
|
133
133
|
flexmock(Time).should_receive(:now).and_return(1000030)
|
134
|
-
@stats.
|
134
|
+
@stats.avg_latency.should be_nil
|
135
135
|
@stats.finish(1000010)
|
136
136
|
@stats.instance_variable_get(:@interval).should == 0.0
|
137
137
|
@stats.instance_variable_get(:@last_start_time).should == @now
|
138
|
-
@stats.instance_variable_get(:@
|
138
|
+
@stats.instance_variable_get(:@avg_latency).should == 2.0
|
139
139
|
@stats.instance_variable_get(:@total).should == 0
|
140
140
|
@stats.instance_variable_get(:@count_per_type).should == {}
|
141
141
|
end
|
@@ -150,7 +150,7 @@ describe RightSupport::Stats::Activity do
|
|
150
150
|
@stats.instance_variable_get(:@total).should == 1
|
151
151
|
@stats.instance_variable_get(:@count_per_type).should == {"test" => 1}
|
152
152
|
@stats.instance_variable_get(:@last_id).should == 0
|
153
|
-
@stats.instance_variable_get(:@
|
153
|
+
@stats.instance_variable_get(:@avg_latency).should == 1.0
|
154
154
|
end
|
155
155
|
|
156
156
|
it "yields to the block" do
|
@@ -227,7 +227,7 @@ describe RightSupport::Stats::Activity do
|
|
227
227
|
@stats.last.should == {"elapsed" => 10, "type" => "test", "active" => true}
|
228
228
|
@stats.finish(@now - 10, "token")
|
229
229
|
@stats.last.should == {"elapsed" => 10, "type" => "test", "active" => false}
|
230
|
-
@stats.instance_variable_get(:@
|
230
|
+
@stats.instance_variable_get(:@avg_latency).should == 2.0
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
@@ -251,17 +251,25 @@ describe RightSupport::Stats::Activity do
|
|
251
251
|
end
|
252
252
|
|
253
253
|
context :all do
|
254
|
-
it "returns all activity aspects that were measured
|
254
|
+
it "returns all activity aspects that were measured" do
|
255
255
|
flexmock(Time).should_receive(:now).and_return(1000020, 1000042)
|
256
256
|
@stats.update
|
257
|
-
@stats.
|
257
|
+
@stats.finish
|
258
|
+
@stats.all.should == {"last" => {"elapsed" => 22}, "total" => 1, "rate" => 0.25, "latency" => 2.2}
|
258
259
|
end
|
259
260
|
|
260
261
|
it "excludes rate if it is not being measured" do
|
261
262
|
@stats = RightSupport::Stats::Activity.new(false)
|
262
|
-
flexmock(Time).should_receive(:now).and_return(
|
263
|
+
flexmock(Time).should_receive(:now).and_return(1000020, 1000042)
|
264
|
+
@stats.update
|
265
|
+
@stats.finish
|
266
|
+
@stats.all.should == {"last" => {"elapsed" => 22}, "total" => 1, "latency" => 2.2}
|
267
|
+
end
|
268
|
+
|
269
|
+
it "excludes latency if it is not being measured" do
|
270
|
+
flexmock(Time).should_receive(:now).and_return(1000020, 1000042)
|
263
271
|
@stats.update
|
264
|
-
@stats.all.should == {"last" => {"elapsed" =>
|
272
|
+
@stats.all.should == {"last" => {"elapsed" => 22}, "total" => 1, "rate" => 0.25}
|
265
273
|
end
|
266
274
|
|
267
275
|
it "includes percentage breakdown when update recorded per type" do
|
@@ -310,6 +318,13 @@ describe RightSupport::Stats::Activity do
|
|
310
318
|
{"last" => {"elapsed" => 10, "type" => "foo"}, "total" => 5, "percent" => {"foo" => 20.0, "bar" => 80.0}, "rate" => 0.18}
|
311
319
|
end
|
312
320
|
|
321
|
+
it "includes latency if provided" do
|
322
|
+
stats = [{"last" => {"elapsed" => 10, "type" => "foo"}, "total" => 1, "percent" => {"foo" => 100.0}, "rate" => 0.5, "latency" => 0.5},
|
323
|
+
{"last" => {"elapsed" => 20, "type" => "bar"}, "total" => 4, "percent" => {"bar" => 100.0}, "rate" => 0.1, "latency" => 0.1}]
|
324
|
+
RightSupport::Stats::Activity.all(stats).should ==
|
325
|
+
{"last" => {"elapsed" => 10, "type" => "foo"}, "total" => 5, "percent" => {"foo" => 20.0, "bar" => 80.0}, "rate" => 0.18, "latency" => 0.18}
|
326
|
+
end
|
327
|
+
|
313
328
|
it "handles nil stat" do
|
314
329
|
stats = [{"last" => {"elapsed" => 10, "type" => "foo"}, "total" => 1, "percent" => {"foo" => 100.0}},
|
315
330
|
nil,
|
@@ -367,6 +382,28 @@ describe RightSupport::Stats::Activity do
|
|
367
382
|
end
|
368
383
|
end
|
369
384
|
|
385
|
+
context :avg_latency do
|
386
|
+
it "computes average latency from multiple average latencies" do
|
387
|
+
stats = [{"total" => 1, "latency" => 0.5},
|
388
|
+
{"total" => 5, "latency" => 0.1},
|
389
|
+
{"total" => 4, "latency" => 0.2}]
|
390
|
+
RightSupport::Stats::Activity.avg_latency(stats, 10).should == 0.18
|
391
|
+
end
|
392
|
+
|
393
|
+
it "handles nil stat" do
|
394
|
+
stats = [{"total" => 1, "latency" => 0.5},
|
395
|
+
nil,
|
396
|
+
{"total" => 5, "latency" => 0.1},
|
397
|
+
nil,
|
398
|
+
{"total" => 4, "latency" => 0.2}]
|
399
|
+
RightSupport::Stats::Activity.avg_latency(stats, 10).should == 0.18
|
400
|
+
end
|
401
|
+
|
402
|
+
it "returns nil if there is no data" do
|
403
|
+
RightSupport::Stats::Activity.avg_latency([], 0).should be_nil
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
370
407
|
context :last do
|
371
408
|
it "determines last activity from multiple last activity stats" do
|
372
409
|
stats = [{"last" => {"elapsed" => 0, "type" => "foo"}, "total" => 1, "percent" => {"foo" => 100.0}},
|
data/spec/stats/helpers_spec.rb
CHANGED
@@ -338,7 +338,7 @@ describe RightSupport::Stats do
|
|
338
338
|
" (1) Mon Jan 12 #{@hr}:46:40 Exception: Test error\n" +
|
339
339
|
" heartbeat : 60 sec\n" +
|
340
340
|
" returns : no queue consumers: 67%, no queue: 33%, total: 3, \n" +
|
341
|
-
" last: no queue consumers (10 sec ago), rate: 1.0/sec\n"
|
341
|
+
" last: no queue consumers (10 sec ago), rate: 1.0/sec, latency: 1.0 sec\n"
|
342
342
|
end
|
343
343
|
|
344
344
|
it "omits exceptions from brokers if exceptions key omitted" do
|
@@ -357,7 +357,7 @@ describe RightSupport::Stats do
|
|
357
357
|
" b2: rs-broker-localhost-5674 failed, disconnects: none, failures: 3 (16 min 40 sec ago w/ 2 retries)\n" +
|
358
358
|
" heartbeat : 60 sec\n" +
|
359
359
|
" returns : no queue consumers: 67%, no queue: 33%, total: 3, \n" +
|
360
|
-
" last: no queue consumers (10 sec ago), rate: 1.0/sec\n"
|
360
|
+
" last: no queue consumers (10 sec ago), rate: 1.0/sec, latency: 1.0 sec\n"
|
361
361
|
end
|
362
362
|
end
|
363
363
|
|
@@ -371,7 +371,7 @@ describe RightSupport::Stats do
|
|
371
371
|
activity.update("more testing")
|
372
372
|
flexmock(Time).should_receive(:now).and_return(1000010)
|
373
373
|
@helpers.activity_str(activity.all).should == "more testing: 75%, testing: 25%, total: 4, last: more testing (10 sec ago), " +
|
374
|
-
"rate: 1.0/sec"
|
374
|
+
"rate: 1.0/sec, latency: 1.0 sec"
|
375
375
|
end
|
376
376
|
|
377
377
|
it 'converts last activity stats to string' do
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.8.
|
4
|
+
version: 2.8.27
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Tony Spataro
|
@@ -13,7 +14,7 @@ authors:
|
|
13
14
|
autorequire:
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
|
-
date: 2014-08-
|
17
|
+
date: 2014-08-08 00:00:00.000000000 Z
|
17
18
|
dependencies: []
|
18
19
|
description: A toolkit of useful, reusable foundation code created by RightScale.
|
19
20
|
email: support@rightscale.com
|
@@ -23,7 +24,7 @@ extra_rdoc_files:
|
|
23
24
|
- LICENSE
|
24
25
|
- README.rdoc
|
25
26
|
files:
|
26
|
-
-
|
27
|
+
- .rspec
|
27
28
|
- CHANGELOG.rdoc
|
28
29
|
- Gemfile
|
29
30
|
- Gemfile.lock
|
@@ -145,25 +146,29 @@ files:
|
|
145
146
|
homepage: https://github.com/rightscale/right_support
|
146
147
|
licenses:
|
147
148
|
- MIT
|
148
|
-
metadata: {}
|
149
149
|
post_install_message:
|
150
150
|
rdoc_options: []
|
151
151
|
require_paths:
|
152
152
|
- lib
|
153
153
|
required_ruby_version: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
154
155
|
requirements:
|
155
|
-
- -
|
156
|
+
- - ! '>='
|
156
157
|
- !ruby/object:Gem::Version
|
157
158
|
version: '0'
|
159
|
+
segments:
|
160
|
+
- 0
|
161
|
+
hash: 3750525095222830475
|
158
162
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
159
164
|
requirements:
|
160
|
-
- -
|
165
|
+
- - ! '>='
|
161
166
|
- !ruby/object:Gem::Version
|
162
167
|
version: '0'
|
163
168
|
requirements: []
|
164
169
|
rubyforge_project:
|
165
|
-
rubygems_version:
|
170
|
+
rubygems_version: 1.8.26
|
166
171
|
signing_key:
|
167
|
-
specification_version:
|
172
|
+
specification_version: 3
|
168
173
|
summary: Reusable foundation code.
|
169
174
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 6010fe3e9ebbaa222eacaf224b0576a36e350f7c
|
4
|
-
data.tar.gz: a4a49a381d7a250a19230b0a3cd848436a51f221
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: a74303a4224cd7bc1ffa4bb3d65df38b4664baa9c55ba31f63327696ff598756c7898d6de68ac625caa8f0e453e5811c73adf8b725a9dc709ebdf200d5f09189
|
7
|
-
data.tar.gz: 9f1d6b77e03702c6e8f83e04633f5fe8708d79f4a790dfbae77a4c860b5da1772576405db4d30d00f8eb19cb15b21d9591b3a91b575806702bd212b68f88cd91
|