Skip to content

Commit 31414e4

Browse files
committed
add more bigger files for upload time measuring
1 parent 4ca4df7 commit 31414e4

File tree

1 file changed

+99
-77
lines changed

1 file changed

+99
-77
lines changed

lib/cloud_controller/benchmark/blobstore.rb

Lines changed: 99 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,78 @@
1+
# frozen_string_literal: true
2+
13
require 'benchmark'
24
require 'find'
35
require 'zip'
6+
require 'tempfile'
7+
require 'fileutils'
8+
require 'securerandom'
49

510
module VCAP::CloudController
611
module Benchmark
712
class Blobstore
13+
SIZES = [
14+
['0.005MB', (0.005 * 1024 * 1024).to_i],
15+
['0.01MB', (0.01 * 1024 * 1024).to_i],
16+
['0.1MB', (0.1 * 1024 * 1024).to_i],
17+
['1MB', 1 * 1024 * 1024],
18+
['10MB', 10 * 1024 * 1024],
19+
['100MB', 100 * 1024 * 1024],
20+
['200MB', 200 * 1024 * 1024],
21+
['300MB', 300 * 1024 * 1024],
22+
['400MB', 400 * 1024 * 1024],
23+
['500MB', 500 * 1024 * 1024],
24+
['600MB', 600 * 1024 * 1024],
25+
['700MB', 700 * 1024 * 1024],
26+
['800MB', 800 * 1024 * 1024],
27+
['900MB', 900 * 1024 * 1024],
28+
['1000MB', 1000 * 1024 * 1024]
29+
].freeze
30+
31+
CHUNK_1MB = '0'.b * (1024 * 1024)
32+
833
def perform
34+
big_droplet_guids = []
935
resource_dir = generate_resources
10-
11-
resource_timing = resource_match(resource_dir)
12-
puts("resource match timing: #{resource_timing * 1000}ms")
36+
log_timing('resource match timing', resource_match(resource_dir))
1337

1438
zip_output_dir = Dir.mktmpdir
1539
zip_file = zip_resources(resource_dir, zip_output_dir)
1640

17-
package_guid, resource_timing = upload_package(zip_file)
18-
puts("package upload timing: #{resource_timing * 1000}ms")
19-
20-
resource_timing = download_package(package_guid, resource_dir)
21-
puts("package download timing: #{resource_timing * 1000}ms")
41+
package_guid, timing = upload_package(zip_file)
42+
log_timing('package upload timing', timing)
43+
log_timing('package download timing', download_package(package_guid, resource_dir))
2244

23-
bytes_read, resource_timing = download_buildpacks(resource_dir)
45+
bytes_read, timing = download_buildpacks(resource_dir)
2446
puts("downloaded #{Buildpack.count} buildpacks, total #{bytes_read} bytes read")
25-
puts("buildpack download timing: #{resource_timing * 1000}ms")
26-
27-
droplet_guid, resource_timing = upload_droplet(zip_file)
28-
puts("droplet upload timing: #{resource_timing * 1000}ms")
29-
30-
resource_timing = download_droplet(droplet_guid, resource_dir)
31-
puts("droplet download timing: #{resource_timing * 1000}ms")
32-
33-
big_droplet_file = Tempfile.new('big-droplet', resource_dir)
34-
big_droplet_file.write('abc' * 1024 * 1024 * 100)
35-
big_droplet_guid, resource_timing = upload_droplet(big_droplet_file.path)
36-
puts("big droplet upload timing: #{resource_timing * 1000}ms")
37-
38-
[
39-
['0.005MB', (0.005 * 1024 * 1024).to_i],
40-
['10MB', 10 * 1024 * 1024],
41-
['200MB', 200 * 1024 * 1024],
42-
['500MB', 500 * 1024 * 1024]
43-
].each do |label, size|
44-
tempfile = Tempfile.new("big-droplet-#{label}", resource_dir)
45-
File.open(tempfile.path, 'wb') do |f|
46-
chunk = '0' * (1024 * 1024) # 1MB chunk
47-
written = 0
48-
while written < size
49-
to_write = [chunk.bytesize, size - written].min
50-
f.write(chunk.byteslice(0, to_write))
51-
written += to_write
52-
end
53-
end
47+
log_timing('buildpack download timing', timing)
5448

55-
big_droplet_guid, resource_timing = upload_droplet(tempfile.path)
56-
puts("big droplet #{label} upload timing: #{resource_timing * 1000}ms")
49+
droplet_guid, timing = upload_droplet(zip_file)
50+
log_timing('droplet upload timing', timing)
51+
log_timing('droplet download timing', download_droplet(droplet_guid, resource_dir))
5752

58-
tempfile.close!
59-
end
53+
SIZES.each do |label, bytes|
54+
Tempfile.create(["big-droplet-#{label}", '.bin'], resource_dir) do |tempfile|
55+
write_file_of_size(tempfile.path, bytes)
6056

61-
resource_timing = download_droplet(big_droplet_guid, resource_dir)
62-
puts("big droplet download timing: #{resource_timing * 1000}ms")
57+
guid, upload_timing = upload_droplet(tempfile.path)
58+
big_droplet_guids << guid
59+
log_timing("big droplet #{label} upload timing", upload_timing)
60+
log_timing("big droplet #{label} download timing", download_droplet(guid, resource_dir))
61+
end
62+
end
6363
ensure
64-
FileUtils.remove_dir(resource_dir, true)
65-
FileUtils.remove_dir(zip_output_dir, true)
66-
package_blobstore_client.delete(package_guid) if package_guid
67-
droplet_blobstore_client.delete(droplet_guid) if droplet_guid
68-
droplet_blobstore_client.delete(big_droplet_guid) if big_droplet_guid
64+
FileUtils.remove_dir(resource_dir, true) if resource_dir
65+
FileUtils.remove_dir(zip_output_dir, true) if zip_output_dir
66+
67+
safe_delete(package_blobstore_client, package_guid)
68+
safe_delete(droplet_blobstore_client, droplet_guid)
69+
Array(big_droplet_guids).each { |g| safe_delete(droplet_blobstore_client, g) }
6970
end
7071

7172
def resource_match(dir_path)
72-
resources = Find.find(dir_path).
73-
select { |f| File.file?(f) }.
74-
map { |f| { 'size' => File.stat(f).size, 'sha1' => Digester.new.digest_path(f) } }
73+
resources = Find.find(dir_path)
74+
.select { |f| File.file?(f) }
75+
.map { |f| { 'size' => File.stat(f).size, 'sha1' => Digester.new.digest_path(f) } }
7576

7677
::Benchmark.realtime do
7778
resource_pool.match_resources(resources)
@@ -83,46 +84,69 @@ def upload_package(package_path)
8384
end
8485

8586
def download_package(package_guid, tmp_dir)
86-
tempfile = Tempfile.new('package-download-benchmark', tmp_dir)
87-
::Benchmark.realtime do
88-
package_blobstore_client.download_from_blobstore(package_guid, tempfile.path)
87+
Tempfile.create('package-download-benchmark', tmp_dir) do |tempfile|
88+
::Benchmark.realtime do
89+
package_blobstore_client.download_from_blobstore(package_guid, tempfile.path)
90+
end
8991
end
9092
end
9193

9294
def download_buildpacks(tmp_dir)
93-
tempfile = Tempfile.new('buildpack-download-benchmark', tmp_dir)
94-
bytes_read = 0
95-
96-
timing = ::Benchmark.realtime do
97-
bytes_read = Buildpack.map do |buildpack|
98-
buildpack_blobstore_client.download_from_blobstore(buildpack.key, tempfile.path)
99-
File.stat(tempfile.path).size
100-
end.sum
95+
Tempfile.create('buildpack-download-benchmark', tmp_dir) do |tempfile|
96+
bytes_read = 0
97+
timing = ::Benchmark.realtime do
98+
bytes_read = Buildpack.map do |buildpack|
99+
buildpack_blobstore_client.download_from_blobstore(buildpack.key, tempfile.path)
100+
File.stat(tempfile.path).size
101+
end.sum
102+
end
103+
[bytes_read, timing]
101104
end
102-
103-
[bytes_read, timing]
104105
end
105106

106107
def upload_droplet(droplet_path)
107108
copy_to_blobstore(droplet_path, droplet_blobstore_client)
108109
end
109110

110111
def download_droplet(droplet_guid, tmp_dir)
111-
tempfile = Tempfile.new('droplet-download-benchmark', tmp_dir)
112-
113-
::Benchmark.realtime do
114-
droplet_blobstore_client.download_from_blobstore(droplet_guid, tempfile.path)
112+
Tempfile.create('droplet-download-benchmark', tmp_dir) do |tempfile|
113+
::Benchmark.realtime do
114+
droplet_blobstore_client.download_from_blobstore(droplet_guid, tempfile.path)
115+
end
115116
end
116117
end
117118

118119
private
119120

121+
def log_timing(label, seconds)
122+
puts("#{label}: #{(seconds * 1000).round(3)}ms")
123+
end
124+
125+
def safe_delete(client, guid)
126+
return if guid.nil?
127+
128+
client.delete(guid)
129+
rescue StandardError => e
130+
# don't fail the benchmark run if cleanup fails
131+
warn("cleanup failed for guid=#{guid}: #{e.class}: #{e.message}")
132+
end
133+
134+
def write_file_of_size(path, bytes)
135+
File.open(path, 'wb') do |f|
136+
remaining = bytes
137+
while remaining > 0
138+
to_write = [CHUNK_1MB.bytesize, remaining].min
139+
f.write(CHUNK_1MB, to_write)
140+
remaining -= to_write
141+
end
142+
end
143+
end
144+
120145
def generate_resources
121146
dir = Dir.mktmpdir
122147

123-
100.times.each do |i|
124-
f = File.open(File.join(dir, i.to_s), 'w')
125-
f.write('foo' * (65_536 + i))
148+
100.times do |i|
149+
File.write(File.join(dir, i.to_s), 'foo' * (65_536 + i))
126150
end
127151

128152
dir
@@ -131,11 +155,9 @@ def generate_resources
131155
def zip_resources(resource_dir, output_dir)
132156
zip_file = File.join(output_dir, 'zipped_package')
133157
Zip::File.open(zip_file, create: true) do |zipfile|
134-
Find.find(resource_dir).
135-
select { |f| File.file?(f) }.
136-
each do |file|
137-
zipfile.add(File.basename(file), file)
138-
end
158+
Find.find(resource_dir)
159+
.select { |f| File.file?(f) }
160+
.each { |file| zipfile.add(File.basename(file), file) }
139161
end
140162
zip_file
141163
end

0 commit comments

Comments
 (0)