diff --git a/lib/ropen/events/event_handler.rb b/lib/ropen/events/event_handler.rb index 400e0b8..d978fcf 100644 --- a/lib/ropen/events/event_handler.rb +++ b/lib/ropen/events/event_handler.rb @@ -17,15 +17,25 @@ def register(event) def run(stdout, stderr) call_events(:start, @command) - handle_output(stdout, :stdout) - handle_output(stderr, :stderr) + def stdout.callback ; :stdout ; end + def stderr.callback ; :stderr ; end + streams = [stdout, stderr] + until streams.empty? + selected, _ = IO.select(streams, nil, nil, 0.1) + next if selected.nil? || selected.empty? + selected.each do |stream| + if stream.eof? then + streams.delete(stream) + else + data = stream.readpartial(1024) + call_events(stream.callback, @command, data) + end + end + end end - # Blocks until the threads started by #run completes. def finish - @threads.each { |t| t.join } call_events(:finish, @command) - @threads.clear end private @@ -36,15 +46,4 @@ def call_events(m, *args) end end - def handle_output(stream, callback_method) - thread = Thread.new do - until stream.eof? - data = stream.readpartial(1024) # TODO: smaller buffer? - call_events(callback_method, @command, data) - end - end - thread.abort_on_exception = true - @threads << thread - end - end \ No newline at end of file diff --git a/spec/fixtures/stderr.txt b/spec/fixtures/stderr.txt new file mode 100644 index 0000000..c26b689 --- /dev/null +++ b/spec/fixtures/stderr.txt @@ -0,0 +1 @@ +Blee \ No newline at end of file diff --git a/spec/fixtures/stdout.txt b/spec/fixtures/stdout.txt new file mode 100644 index 0000000..4ab4229 --- /dev/null +++ b/spec/fixtures/stdout.txt @@ -0,0 +1,2 @@ +Blah +Blah \ No newline at end of file diff --git a/spec/ropen/events/event_handler_spec.rb b/spec/ropen/events/event_handler_spec.rb index d393d29..d30765b 100644 --- a/spec/ropen/events/event_handler_spec.rb +++ b/spec/ropen/events/event_handler_spec.rb @@ -12,31 +12,27 @@ @handler = Ropen::Events::EventHandler.new(@command) end - def pretend_to_run_stream - @stdout.should_receive(:eof?).and_return(false, false, true) - @stdout.should_receive(:readpartial).with(an_instance_of(Numeric)).and_return("blah", "blee") - - @stderr.should_receive(:eof?).and_return(false, true) - @stderr.should_receive(:readpartial).with(an_instance_of(Numeric)).and_return("ERROR") - - @handler.register(@event) - @handler.run(@stdout, @stderr) - @handler.finish - end - it "should register events" do @handler.register(@event) @handler.register(@event) @handler.events.should == [@event, @event] end - it "should run events on the output of a stream" do + def pretend_to_run_stream + File.open(fixture("stdout.txt")) do |f1| + File.open(fixture("stderr.txt")) do |f2| + @handler.run(f1, f2) + @handler.finish + end + end + end + + it "should run events on the output of STDOUT and STDERR" do + @handler.register(@event) @event.should_receive(:start).with(@command).ordered - @event.should_receive(:stdout).with(@command, "blah").ordered - @event.should_receive(:stdout).with(@command, "blee").ordered - @event.should_receive(:stderr).with(@command, "ERROR").ordered + @event.should_receive(:stdout).with(@command, "Blah\nBlah").ordered + @event.should_receive(:stderr).with(@command, "Blee").ordered @event.should_receive(:finish).with(@command).ordered - pretend_to_run_stream end @@ -44,8 +40,7 @@ def pretend_to_run_stream @event.should_receive(:start).any_number_of_times.and_throw(:halt) @event.should_receive(:stdout).any_number_of_times.and_throw(:halt) @event.should_receive(:stderr).any_number_of_times.and_throw(:halt) - @event.should_receive(:finish).any_number_of_times.and_throw(:halt) - + @event.should_receive(:finish).any_number_of_times.and_throw(:halt) pretend_to_run_stream end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 44592b9..c92a8b3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,6 +4,7 @@ Spec::Runner.configure do |config| def fixture(name) - File.join(".", "spec", "fixtures", "#{name}.rb") + filename = name.is_a?(Symbol) ? "#{name}.rb" : name + File.join(".", "spec", "fixtures", filename) end end \ No newline at end of file