em-zipper 0.0.3 → 0.0.4
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/benchmarkz/em-zipper-bm.rb +105 -0
- data/benchmarkz/em-zipper.rb +34 -32
- data/lib/em-zipper.rb +2 -0
- data/lib/em-zipper/base.rb +21 -49
- data/lib/em-zipper/chunks.rb +47 -0
- data/lib/em-zipper/entry.rb +46 -0
- data/lib/em-zipper/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cb4c9228359aa7f2d20d70f6ba45d8065fe3a7d
|
4
|
+
data.tar.gz: b2b4bdbbe95c3b5f97864e3cdf63999c087c1543
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f853b18fc71e141fabacba3f2134c8af4e2a1ddb20c0801291f065008930aaeb9f8eb73845b4242923803e5475c016e1cb1eb826cb553cbfa9bc6d7dd523ec6
|
7
|
+
data.tar.gz: d2b930387a4d820a79f8f7fcc67a23150722fef8b280680354a99a0605fa17792d1a4ff989387212eed6ac65aea2aa55f4b399ea079efa4f0c8609a430c73a88
|
@@ -0,0 +1,105 @@
|
|
1
|
+
$: << File.expand_path('../lib', __FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require "benchmark"
|
4
|
+
require 'em-zipper'
|
5
|
+
require 'net/http'
|
6
|
+
|
7
|
+
|
8
|
+
sites = %w(http://s3.amazonaws.com/ping-em-assets/sample1.txt http://s3.amazonaws.com/ping-em-assets/sample2.txt)
|
9
|
+
files = %w(sample1.txt sample2.txt).map do |file_name|
|
10
|
+
File.join(File.expand_path("./examples/files"), file_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
n = 10
|
14
|
+
@count = 0
|
15
|
+
|
16
|
+
def em_zipper(collection, n)
|
17
|
+
zip = EM::Zipper.new(collection, StringIO.new).zip!
|
18
|
+
zip.callback do |io|
|
19
|
+
io.close
|
20
|
+
@count = @count + 1
|
21
|
+
EM.stop if @count == n
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def rubyzip(collection, n)
|
26
|
+
::Zip::ZipOutputStream.write_buffer do |zip|
|
27
|
+
collection.each do |file_path|
|
28
|
+
zip.put_next_entry(File.basename(file_path))
|
29
|
+
|
30
|
+
begin
|
31
|
+
if file_path.match(/\Ahttps?:\/\//)
|
32
|
+
uri = URI file_path
|
33
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
34
|
+
request = Net::HTTP::Get.new uri
|
35
|
+
|
36
|
+
http.request request do |response|
|
37
|
+
response.read_body { |chunk| zip << chunk }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
else
|
41
|
+
file = File.open file_path
|
42
|
+
while chunk = file.read_nonblock(16384)
|
43
|
+
zip << chunk
|
44
|
+
end
|
45
|
+
end
|
46
|
+
rescue EOFError
|
47
|
+
# /
|
48
|
+
ensure
|
49
|
+
file && file.close
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
# //
|
57
|
+
|
58
|
+
|
59
|
+
marks = Benchmark.benchmark do |b|
|
60
|
+
b.report("[file] em-zipper") do
|
61
|
+
@count = 0
|
62
|
+
|
63
|
+
EM.run do
|
64
|
+
n.times do
|
65
|
+
EM.next_tick { em_zipper(files, n) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
b.report('[file] rubyzip') do
|
71
|
+
n.times do
|
72
|
+
rubyzip(files, n)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
b.report("[net] em-zipper") do
|
77
|
+
@count = 0
|
78
|
+
|
79
|
+
EM.run do
|
80
|
+
n.times do
|
81
|
+
EM.next_tick { em_zipper(sites, n) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
b.report('[net] rubyzip') do
|
87
|
+
n.times do
|
88
|
+
rubyzip(sites, n)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
puts marks
|
94
|
+
|
95
|
+
# //
|
96
|
+
#
|
97
|
+
# [file] em-zipper 2.780000 0.040000 2.820000 ( 2.829317)
|
98
|
+
# [file] rubyzip 2.690000 0.030000 2.720000 ( 2.740578)
|
99
|
+
# [net] em-zipper 3.060000 0.150000 3.210000 ( 5.076801)
|
100
|
+
# [net] rubyzip 3.020000 0.090000 3.110000 ( 6.962918)
|
101
|
+
# 2.780000 0.040000 2.820000 ( 2.829317)
|
102
|
+
# 2.690000 0.030000 2.720000 ( 2.740578)
|
103
|
+
# 3.060000 0.150000 3.210000 ( 5.076801)
|
104
|
+
# 3.020000 0.090000 3.110000 ( 6.962918)
|
105
|
+
|
data/benchmarkz/em-zipper.rb
CHANGED
@@ -13,7 +13,13 @@ end
|
|
13
13
|
|
14
14
|
Tach.meter(10) do
|
15
15
|
tach('[file] em-zipper') do |n|
|
16
|
-
|
16
|
+
@count = 0
|
17
|
+
|
18
|
+
EM.run do
|
19
|
+
n.times do |i|
|
20
|
+
EM.next_tick { em_zipper files, n }
|
21
|
+
end
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
25
|
tach('[file] rubyzip') do |n|
|
@@ -21,7 +27,13 @@ Tach.meter(10) do
|
|
21
27
|
end
|
22
28
|
|
23
29
|
tach('[net] em-zipper') do |n|
|
24
|
-
|
30
|
+
@count = 0
|
31
|
+
|
32
|
+
EM.run do
|
33
|
+
n.times do |i|
|
34
|
+
EM.next_tick { em_zipper files, n }
|
35
|
+
end
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
39
|
tach('[net] rubyzip') do |n|
|
@@ -30,21 +42,11 @@ Tach.meter(10) do
|
|
30
42
|
|
31
43
|
|
32
44
|
def em_zipper(collection, n)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
zip.callback do |io|
|
39
|
-
io.close
|
40
|
-
count = count + 1
|
41
|
-
EM.stop if count == n
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
n.times do |i|
|
46
|
-
EM.next_tick(&em_zipper)
|
47
|
-
end
|
45
|
+
zip = EM::Zipper.new(collection, StringIO.new).zip!
|
46
|
+
zip.callback do |io|
|
47
|
+
io.close
|
48
|
+
@count = @count + 1
|
49
|
+
EM.stop if @count == n
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -85,27 +87,27 @@ end
|
|
85
87
|
# File sizes 1.5mb, 503kb
|
86
88
|
#
|
87
89
|
# x10
|
88
|
-
#
|
89
|
-
# | tach | total
|
90
|
-
#
|
91
|
-
# | [
|
92
|
-
#
|
93
|
-
# | [
|
94
|
-
#
|
95
|
-
# | [
|
96
|
-
#
|
97
|
-
# | [
|
98
|
-
#
|
90
|
+
# +------------------+-----------+
|
91
|
+
# | tach | total |
|
92
|
+
# +------------------+-----------+
|
93
|
+
# | [net] em-zipper | 2.727529 |
|
94
|
+
# +------------------+-----------+
|
95
|
+
# | [file] em-zipper | 2.753560 |
|
96
|
+
# +------------------+-----------+
|
97
|
+
# | [file] rubyzip | 8.035955 |
|
98
|
+
# +------------------+-----------+
|
99
|
+
# | [net] rubyzip | 10.780907 |
|
100
|
+
# +------------------+-----------+
|
99
101
|
#
|
100
102
|
# x100
|
101
103
|
# +------------------+-----------+
|
102
104
|
# | tach | total |
|
103
105
|
# +------------------+-----------+
|
104
|
-
# | [file] em-zipper | 27.
|
106
|
+
# | [file] em-zipper | 27.435623 |
|
105
107
|
# +------------------+-----------+
|
106
|
-
# | [net] em-zipper |
|
108
|
+
# | [net] em-zipper | 27.858313 |
|
107
109
|
# +------------------+-----------+
|
108
|
-
# | [net] rubyzip |
|
110
|
+
# | [net] rubyzip | 58.306401 |
|
109
111
|
# +------------------+-----------+
|
110
|
-
# | [file] rubyzip |
|
112
|
+
# | [file] rubyzip | 60.937767 |
|
111
113
|
# +------------------+-----------+
|
data/lib/em-zipper.rb
CHANGED
data/lib/em-zipper/base.rb
CHANGED
@@ -11,11 +11,14 @@ module EventMachine
|
|
11
11
|
@files = files
|
12
12
|
@zos = zos
|
13
13
|
@fqueue = EM::Queue.new
|
14
|
+
@count = 0
|
14
15
|
end
|
15
16
|
|
16
17
|
def zip!
|
17
|
-
files.each
|
18
|
-
|
18
|
+
files.each do |file_path|
|
19
|
+
EM.next_tick { chunk_data(file_path) }
|
20
|
+
end
|
21
|
+
fqueue.pop(&write_entry) # begin queue, first file to chunk will be issued this call
|
19
22
|
|
20
23
|
self # ...new(..., ...).zip!
|
21
24
|
end
|
@@ -23,65 +26,34 @@ module EventMachine
|
|
23
26
|
|
24
27
|
private
|
25
28
|
|
26
|
-
def file_name(file_path)
|
27
|
-
File.basename file_path
|
28
|
-
end
|
29
|
-
|
30
29
|
def close_zos
|
31
30
|
zos.close if zos.io.is_a?(File) # close the io if it's a file
|
32
|
-
succeed zos.close_buffer
|
31
|
+
succeed zos.close_buffer # return the zos
|
33
32
|
end
|
34
33
|
|
35
|
-
def
|
36
|
-
proc do |
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
def write_entry
|
35
|
+
proc do |args|
|
36
|
+
file_path = args[0]
|
37
|
+
q = args[1]
|
38
|
+
|
39
|
+
entry = Entry.new(file_path, q, zos).write!
|
40
|
+
entry.callback do
|
41
|
+
@count = @count + 1
|
40
42
|
|
41
|
-
if
|
42
|
-
close_zos
|
43
|
-
EM.next_tick { fqueue.pop(&next_entry_non_block) }
|
43
|
+
if files.size == @count
|
44
|
+
close_zos
|
44
45
|
else
|
45
|
-
EM.next_tick {
|
46
|
+
EM.next_tick { fqueue.pop(&write_entry) }
|
46
47
|
end
|
47
48
|
end
|
48
|
-
|
49
|
-
defer = EM::DefaultDeferrable.new
|
50
|
-
defer.callback do
|
51
|
-
# begin the entry when we have all the data
|
52
|
-
new_entry = ::Zip::ZipEntry.new '-', file_name(file_path)
|
53
|
-
zos.put_next_entry(new_entry)
|
54
|
-
|
55
|
-
EM.next_tick { cqueue.pop(&chunky) } if cqueue.size > 0
|
56
|
-
end
|
57
|
-
defer.errback { puts 'error' }
|
58
|
-
|
59
|
-
_chunk_method = file_path.match(/\Ahttps?:\/\//) ? :chunk_http : :chunk_file
|
60
|
-
__send__ _chunk_method, file_path, cqueue, defer
|
61
49
|
end
|
62
50
|
end
|
63
51
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
begin
|
69
|
-
q.push file.read_nonblock(16384)
|
70
|
-
EM.next_tick(&fr)
|
71
|
-
rescue EOFError
|
72
|
-
file.close
|
73
|
-
EM.next_tick { d.succeed }
|
74
|
-
end
|
52
|
+
def chunk_data(file_path)
|
53
|
+
chunks = Chunks.new(file_path).chop!
|
54
|
+
chunks.callback do |chunk_q|
|
55
|
+
EM.next_tick { fqueue.push [file_path, chunk_q] }
|
75
56
|
end
|
76
|
-
|
77
|
-
EM.next_tick(&fr)
|
78
|
-
end
|
79
|
-
|
80
|
-
def chunk_http(uri, q, d)
|
81
|
-
http = EventMachine::HttpRequest.new(uri).get
|
82
|
-
http.errback { EM.next_tick { d.fail } }
|
83
|
-
http.callback { EM.next_tick { d.succeed } }
|
84
|
-
http.stream { |chunk| q.push chunk }
|
85
57
|
end
|
86
58
|
end
|
87
59
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Zipper
|
3
|
+
class Chunks
|
4
|
+
include EventMachine::Deferrable
|
5
|
+
|
6
|
+
attr_reader :file_path, :q
|
7
|
+
|
8
|
+
def initialize(file_path)
|
9
|
+
@file_path = file_path
|
10
|
+
@q = EM::Queue.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def chop!
|
14
|
+
_chunk_method = file_path.match(/\Ahttps?:\/\//) ? :chunk_http : :chunk_file
|
15
|
+
__send__ _chunk_method
|
16
|
+
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def chunk_file
|
24
|
+
file = File.open file_path
|
25
|
+
|
26
|
+
fr = proc do
|
27
|
+
begin
|
28
|
+
q.push file.read_nonblock(16384)
|
29
|
+
EM.next_tick(&fr)
|
30
|
+
rescue EOFError
|
31
|
+
file.close
|
32
|
+
succeed(q)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
EM.next_tick(&fr)
|
37
|
+
end
|
38
|
+
|
39
|
+
def chunk_http
|
40
|
+
http = EventMachine::HttpRequest.new(file_path).get
|
41
|
+
http.errback { fail }
|
42
|
+
http.callback { succeed(q) }
|
43
|
+
http.stream { |chunk| q.push chunk }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module EventMachine
|
2
|
+
module Zipper
|
3
|
+
class Entry
|
4
|
+
include EventMachine::Deferrable
|
5
|
+
|
6
|
+
attr_reader :file_path, :chunks, :out
|
7
|
+
|
8
|
+
def initialize(file_path, chunks, out)
|
9
|
+
@file_path = file_path
|
10
|
+
@chunks = chunks
|
11
|
+
@out = out
|
12
|
+
end
|
13
|
+
|
14
|
+
def write!
|
15
|
+
create_entry
|
16
|
+
EM.next_tick { chunks.pop(&write_chunks) }
|
17
|
+
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def write_chunks
|
25
|
+
proc do |chunk|
|
26
|
+
out << chunk
|
27
|
+
|
28
|
+
if chunks.empty?
|
29
|
+
EM.next_tick { succeed }
|
30
|
+
else
|
31
|
+
EM.next_tick { chunks.pop(&write_chunks) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def file_name
|
37
|
+
@file_namem ||= File.basename file_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_entry
|
41
|
+
new_entry = ::Zip::ZipEntry.new '-', file_name
|
42
|
+
out.put_next_entry(new_entry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/em-zipper/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: em-zipper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yung Hwa Kwon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -63,6 +63,7 @@ files:
|
|
63
63
|
- .ruby-version
|
64
64
|
- Gemfile
|
65
65
|
- Gemfile.lock
|
66
|
+
- benchmarkz/em-zipper-bm.rb
|
66
67
|
- benchmarkz/em-zipper.rb
|
67
68
|
- em-zipper.gemspec
|
68
69
|
- examples/async_sinatra.md
|
@@ -72,6 +73,8 @@ files:
|
|
72
73
|
- examples/io.rb
|
73
74
|
- lib/em-zipper.rb
|
74
75
|
- lib/em-zipper/base.rb
|
76
|
+
- lib/em-zipper/chunks.rb
|
77
|
+
- lib/em-zipper/entry.rb
|
75
78
|
- lib/em-zipper/stream_io.rb
|
76
79
|
- lib/em-zipper/version.rb
|
77
80
|
- lib/em-zipper/zip_output_stream.rb
|