em-zipper 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64af8eac1c0ad6532476956a5b9852c8cc6d8acf
4
- data.tar.gz: 16ef90ab41a5ee6416f5ac4b0979aa4b6ef71f21
3
+ metadata.gz: 9cb4c9228359aa7f2d20d70f6ba45d8065fe3a7d
4
+ data.tar.gz: b2b4bdbbe95c3b5f97864e3cdf63999c087c1543
5
5
  SHA512:
6
- metadata.gz: ece25c89c5c737918b9bc3a43c0aada19034166523091441d3c52e1c5ebde846ba35d9e21ffeefe1f3ad0b18c07cb85f80a1d95301cf9ff7946f415851ce36e2
7
- data.tar.gz: 08fa21a4d870487480b779d616fdcd0cf265e27d27aaa526d0fc827466144110a169d7871558c6d8b0141deaf0b35f13e88b9060d7dd0ac4504eb55392daafa2
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
+
@@ -13,7 +13,13 @@ end
13
13
 
14
14
  Tach.meter(10) do
15
15
  tach('[file] em-zipper') do |n|
16
- em_zipper files, n
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
- em_zipper sites, n
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
- EventMachine.run do
34
- count = 0
35
-
36
- em_zipper = proc do
37
- zip = EM::Zipper.new(collection, StringIO.new).zip!
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
- # | [file] em-zipper | 2.849514 |
92
- # +------------------+----------+
93
- # | [net] em-zipper | 3.646211 |
94
- # +------------------+----------+
95
- # | [net] rubyzip | 5.765788 |
96
- # +------------------+----------+
97
- # | [file] rubyzip | 9.334782 |
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.344414 |
106
+ # | [file] em-zipper | 27.435623 |
105
107
  # +------------------+-----------+
106
- # | [net] em-zipper | 48.246017 |
108
+ # | [net] em-zipper | 27.858313 |
107
109
  # +------------------+-----------+
108
- # | [net] rubyzip | 60.066137 |
110
+ # | [net] rubyzip | 58.306401 |
109
111
  # +------------------+-----------+
110
- # | [file] rubyzip | 66.197528 |
112
+ # | [file] rubyzip | 60.937767 |
111
113
  # +------------------+-----------+
data/lib/em-zipper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'eventmachine'
2
2
 
3
3
  require 'em-zipper/base'
4
+ require 'em-zipper/entry'
5
+ require 'em-zipper/chunks'
4
6
  require 'em-zipper/zip_output_stream'
5
7
  require 'em-zipper/stream_io'
6
8
 
@@ -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 { |file_path| fqueue.push file_path }
18
- fqueue.pop(&next_entry_non_block)
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 # return the zos
31
+ succeed zos.close_buffer # return the zos
33
32
  end
34
33
 
35
- def next_entry_non_block
36
- proc do |file_path|
37
- cqueue = EM::Queue.new
38
- chunky = proc do |chunk|
39
- zos << chunk
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 cqueue.empty?
42
- close_zos and return if fqueue.empty?
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 { cqueue.pop(&chunky) }
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 chunk_file(file_path, q, d)
65
- file = File.open file_path
66
-
67
- fr = proc do
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
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module Zipper
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
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.3
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-16 00:00:00.000000000 Z
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