Hi,
I was trying to run multiple ftp.putbinaryfile jobs and noticed that if
I run more than say 2 threads on my PIII 933, My CPU usage hits 100% and
my IO stays about the same, even though I am nowhere close to my
theorectical limit. Here’s the original code.1.upto(5) {|server_suffix|
puts “starting send to DL360#{server_suffix}”
threads[server_suffix] = Thread.new {
ftp[server_suffix].putbinaryfile ‘100recs.tar.gz’,
‘100recs.tar.gz’telnet[server_suffix].cmd 'tar -xzf 100recs.tar.gz'
}
}
threads[1…5].each {|thread| thread.join}My connection should actually be able to handle about 20 of these
threads at a time. What I noticed was that of course ftp.rb’s routines
are block oriented and pass everything through yield to a block for
processing. I was wondering if it would be good for me or someone to
add non block-oriented functions that perhaps even memory map and or
buffer files where appropriate to save cpu time.
Can you try this patch?
Shugo
Index: lib/net/ftp.rb
···
===================================================================
RCS file: /src/ruby/lib/net/ftp.rb,v
retrieving revision 1.10
diff -u -r1.10 ftp.rb
— lib/net/ftp.rb 2002/06/11 04:20:11 1.10
+++ lib/net/ftp.rb 2002/06/11 08:35:51
@@ -261,26 +261,21 @@
@welcome = resp
end
- def retrbinary(cmd, blocksize, rest_offset = nil, callback = Proc.new)
- def retrbinary(cmd, blocksize, rest_offset = nil)
synchronize do
voidcmd(“TYPE I”)
conn = transfercmd(cmd, rest_offset)
loop do
data = conn.read(blocksize)
break if data == nil
-
callback.call(data)
-
endyield(data)
conn.close
voidresp
end
end
- def retrlines(cmd, callback = nil)
-
if block_given?
- callback = Proc.new
-
elsif not callback.is_a?(Proc)
- callback = Proc.new {|line| print line, “\n”}
-
end
- def retrlines(cmd)
synchronize do
voidcmd(“TYPE A”)
conn = transfercmd(cmd)
@@ -292,18 +287,14 @@
elsif line[-1] == ?\n
line = line[0 … -2]
end
-
callback.call(line)
-
endyield(line)
conn.close
voidresp
end
end
- def storbinary(cmd, file, blocksize, rest_offset = nil, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
- def storbinary(cmd, file, blocksize, rest_offset = nil, &block)
synchronize do
voidcmd(“TYPE I”)
conn = transfercmd(cmd, rest_offset)
@@ -311,18 +302,14 @@
buf = file.read(blocksize)
break if buf == nil
conn.write(buf)
-
callback.call(buf) if use_callback
-
endyield(buf) if block
conn.close
voidresp
end
end
- def storlines(cmd, file, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
- def storlines(cmd, file, &block)
synchronize do
voidcmd(“TYPE A”)
conn = transfercmd(cmd)
@@ -333,7 +320,7 @@
buf = buf.chomp + CRLF
end
conn.write(buf)
-
callback.call(buf) if use_callback
-
yield(buf) if block
end
conn.close
voidresp
@@ -341,11 +328,7 @@
enddef getbinaryfile(remotefile, localfile,
-
blocksize = DEFAULT_BLOCKSIZE, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
-
rest_offset = File.size?(localfile)blocksize = DEFAULT_BLOCKSIZE, &block) if @resume
f = open(localfile, “a”)
@@ -357,24 +340,20 @@
f.binmode
retrbinary("RETR " + remotefile, blocksize, rest_offset) do |data|
f.write(data)
-
callback.call(data) if use_callback
-
endyield(data) if block
ensure
f.close
end
end
- def gettextfile(remotefile, localfile, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
- def gettextfile(remotefile, localfile, &block)
f = open(localfile, “w”)
begin
retrlines("RETR " + remotefile) do |line|
line = line + @return_code
f.write(line)
-
callback.call(line) if use_callback
-
yield(line) if block
end
ensure
f.close
@@ -382,11 +361,7 @@
enddef putbinaryfile(localfile, remotefile,
-
blocksize = DEFAULT_BLOCKSIZE, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
-
rest_offset = size(remotefile)blocksize = DEFAULT_BLOCKSIZE, &block) if @resume
else
@@ -395,24 +370,16 @@
f = open(localfile)
begin
f.binmode
- storbinary("STOR " + remotefile, f, blocksize, rest_offset) do |data|
-
callback.call(data) if use_callback
- end
- storbinary("STOR " + remotefile, f, blocksize, rest_offset, &block)
ensure
f.close
end
end
- def puttextfile(localfile, remotefile, callback = nil)
-
if block_given?
- callback = Proc.new
-
end
-
use_callback = callback.is_a?(Proc)
- def puttextfile(localfile, remotefile, &block)
f = open(localfile)
begin
- storlines("STOR " + remotefile, f) do |line|
-
callback.call(line) if use_callback
- end
- storlines("STOR " + remotefile, f, &block)
ensure
f.close
end