Skip to content
Permalink
Browse files

move code from cocaine

  • Loading branch information
mmangino committed Feb 6, 2018
1 parent 107e149 commit 77deb17e04eb56cdda4ad6c02ed5757d1290e089
Showing with 50 additions and 5 deletions.
  1. +37 −5 lib/terrapin/command_line/multi_pipe.rb
  2. +13 −0 spec/support/nonblocking_examples.rb
@@ -29,19 +29,51 @@ def close_write
end

def read
@stdout_output = read_stream(@stdout_in)
@stderr_output = read_stream(@stderr_in)
read_streams(@stdout_in, @stderr_in)
end

def close_read
@stdout_in.close
begin
@stdout_in.close
rescue IOError
# do nothing
end

begin
@stderr_in.close
rescue IOError
# do nothing
end
end

def read_streams(output, error)
@stdout_output = ""
@stderr_output = ""
read_fds = [output, error]
while !read_fds.empty?
to_read, = IO.select(read_fds)
if to_read.include?(output)
@stdout_output << read_stream(output)
read_fds.delete(output) if output.closed?
end

if to_read.include?(error)
@stderr_output << read_stream(error)
read_fds.delete(error) if error.closed?
end
end
end

def read_stream(io)
result = ""
while partial_result = io.read(8192)
result << partial_result
begin
while partial_result = io.read_nonblock(8192)
result << partial_result
end
rescue EOFError, Errno::EPIPE
io.close
rescue Errno::EINTR, Errno::EWOULDBLOCK, Errno::EAGAIN
# do nothing
end
result
end
@@ -1,4 +1,17 @@
shared_examples_for "a command that does not block" do
it "does not block if the command output a lot on stderr" do
cmd = Terrapin::CommandLine.new(
"ruby",
"-e '$stdout.puts %{hello}; $stderr.puts %{goodbye}*10_000'",
:swallow_stderr => false
)
Timeout.timeout(5) do
cmd.run
end
expect(cmd.command_output).to eq "hello\n"
expect(cmd.command_error_output).to eq "#{"goodbye" * 10_000}\n"
end

it 'does not block if the command outputs a lot of data' do
garbage_file = Tempfile.new("garbage")
10.times{ garbage_file.write("A" * 1024 * 1024) }

0 comments on commit 77deb17

Please sign in to comment.
You can’t perform that action at this time.