F1 dreamer | 28 Jun 2012 16:12

Asynchronous IO

I have found quite a bit on the web regarding asynchronous IO, but
nothing really works the way I expected it to in my case.

I'm new to this but herewith my question anyway:

Currently I'm using OI.popen to open a new pipe to another process, and
I feed commands to it; but sometimes the other process could run for
multiple minutes before closing the pipe; and only at that stage can I
then see the output. Now, what I really need is to see the output of the
process as it writes to stdout already and not only when closing the
pipe?

Ta.

--

-- 
Posted via http://www.ruby-forum.com/.

Andrea Dallera | 28 Jun 2012 16:36

Re: Asynchronous IO

 This is far from a clean solution, mind you:

    pipe = IO.popen("command", "options")
    Thread.new do
      while(true)
        p pipe.gets        
      end
    end
    pipe.puts("I'm writing this on the pipe")

You should see the process's output in your STDOUT.

Andrea
 
--
 
http://usingimho.wordpress.com
http://github.com/bolthar


Da: "F1 dreamer" lists <at> ruby-forum.com
A: ruby-talk <at> ruby-lang.org
Cc:
Data: Thu, 28 Jun 2012 23:12:28 +0900
Oggetto: Asynchronous IO

> I have found quite a bit on the web regarding asynchronous IO, but
> nothing really works the way I expected it to in my case.
>
> I'm new to this but herewith my question anyway:
>
> Currently I'm using OI.popen to open a new pipe to another process, and
> I feed commands to it; but sometimes the other process could run for
> multiple minutes before closing the pipe; and only at that stage can I
> then see the output. Now, what I really need is to see the output of the
> process as it writes to stdout already and not only when closing the
> pipe?
>
> Ta.
>
> --
> Posted via http://www.ruby-forum.com/.
>
Robert Klemme | 29 Jun 2012 16:54
Gravatar

Re: Asynchronous IO

On Thu, Jun 28, 2012 at 4:36 PM, Andrea Dallera
<andrea <at> andreadallera.com> wrote:
>  This is far from a clean solution, mind you:

Things to improve:

- use the block form of IO.popen
- close writing when finished
- join on the reader thread

>     pipe = IO.popen("command", "options")
>     Thread.new do
>       while(true)
>         p pipe.gets
>       end
>     end
>     pipe.puts("I'm writing this on the pipe")
>
> You should see the process's output in your STDOUT.

$ ruby19 popen.rb
  0.000 main      : "started"
  0.040 writer    : "about to write first line"
  0.041 reader    : "     1\tfirst line\n"
  1.041 writer    : "about to write second line"
  1.041 reader    : "     2\tsecond line\n"
  6.041 writer    : "about to write last line"
  6.041 reader    : "     3\tlast line\n"
  6.041 writer    : "closed"
  6.041 writer    : "joined"
  6.042 main      : "finished"

Kind regards

robert

--

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
Attachment (popen.rb): application/octet-stream, 574 bytes
Jeremy Bopp | 28 Jun 2012 17:01
Gravatar

Re: Asynchronous IO

On 06/28/2012 09:12 AM, F1 dreamer wrote:
> Currently I'm using OI.popen to open a new pipe to another process, and
> I feed commands to it; but sometimes the other process could run for
> multiple minutes before closing the pipe; and only at that stage can I
> then see the output. Now, what I really need is to see the output of the
> process as it writes to stdout already and not only when closing the
> pipe?

The problem you're probably facing is due to the program being run via
popen buffering its output.  This is pretty normal when the program is
outputting to a pipe, as it does when run via popen.

This page has a reasonable summary of things:

http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Unless the program you're trying to run has some specific options
available to force it to disable buffering, you're probably going to be
forced to write your own sort of popen method that allocates a pty
rather than a pipe for interaction with the program.

-Jeremy

F1 dreamer | 29 Jun 2012 07:39

Re: Asynchronous IO

Hi guys,

Thanks a lot, I'll go through and try everything you guys suggested and 
let you know.

Thank you!

--

-- 
Posted via http://www.ruby-forum.com/.

Sean O'Halpin | 30 Jun 2012 00:03
Picon
Gravatar

Re: Asynchronous IO

Hi,

> Currently I'm using OI.popen to open a new pipe to another process, and
> I feed commands to it; but sometimes the other process could run for
> multiple minutes before closing the pipe; and only at that stage can I
> then see the output. Now, what I really need is to see the output of the
> process as it writes to stdout already and not only when closing the
> pipe?

I just so happen to have been mucking about with the PTY
(pseudoterminal) library under ruby 1.9.3.
A pseudoterminal might be what you need if you can't change the
buffering of the programs you're trying to manage.

I've put my current test script here: https://gist.github.com/3020873

You'll need to play with the options to get the result you want -
there's no really generic way to automatically manage interactive
programs that expect to interact with a person.

I've found it useful to run the test script in one terminal with the
--debug option and in another use

  tail -F dbg.log

to see exactly what is passing between the parent and the child process.

As an example you could look at the differences between:

  ./pty-test.rb --debug irb --simple-prompt
  ./pty-test.rb --debug --raw irb --simple-prompt
  ./pty-test.rb --debug --errpipe --raw irb --simple-prompt

Another one to try is

  ./pty-test.rb --debug --errpipe --raw vi

Regards,
Sean


Gmane