Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-29 Thread Laurent Bartholdi
Thanks to all for the thorough replies!

Of course I'm not really interested in interaction with od; I just used it 
as an example of a program that reads input and produces output accordingly.

I wanted to interface to a program (gap) that flushes its output on 
terminals, but seemingly not on pipes.

That leaves 2 options: either change gap so that it doesn't buffer its 
output, or run the process on a pseudo-tty.

In all cases, the problem isn't with Julia :)

On Sunday, 28 June 2015 22:39:36 UTC+2, Jameson wrote:

 yes, it is the fault of `od`. you can see this by using `cat` instead and 
 observing that it works. if you play around with the thresholds in `od`, 
 you will observe that it is doing block-buffering of 4096 byte chunks when 
 the input is a pipe.

 Unless you turn on write buffering (with `buffer_writes(si)`), the `write` 
 function implicitly calls `flush`, and will block the task until the write 
 completes (the actual `flush` function is a no-op). Therefore, it's best to 
 call write in a separate task if you are processing both ends of the pipe:

 julia (so,si,pr) = readandwrite(`od`)
 (Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`od`, 
 ProcessRunning))

 julia @async write(si,repeat(test\n,1))
 Task (done) @0x7fe37aa0daa0

 (note, the line_buffered property has no effect)

 Note that Base.readavailable returns a random, non-zero number of bytes, 
 which is presumably not what you want?

 julia Base.readavailable(so)
 135168-element Array{UInt8,1}:
 ...
 julia Base.readavailable(so)
 61440-element Array{UInt8,1}:
 ...

 In order to get the full output, you need to instead call:
 julia close(si)
 julia readall(so)


 On Sun, Jun 28, 2015 at 9:08 AM Jeff Waller trut...@gmail.com 
 javascript: wrote:



 On Saturday, June 27, 2015 at 5:03:53 PM UTC-4, ele...@gmail.com wrote:

 Is your od program flushing its output?  Maybe its stuck in its internal 
 buffers, not in the pipe.


 nah man, if it's it's od, it's not going to do that, the only thing 
 simpler is cat; I suppose you could try cat.

 What happens when you do something like this?

 *julia **fromStream,toStream,p=readandwrite(`cat`)*

 *(Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`cat`, 
 ProcessRunning))*


 *julia **toStream.line_buffered*

 *true*


 *julia **toStream.line_buffered = false*

 *false*


 *julia **fromStream.line_buffered = false*

 *false*


 *julia **write(toStream,x)*

 *1*


 *julia **readavailable(fromStream)*

 *1-element Array{UInt8,1}:*

 * 0x78*



Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-28 Thread Jeff Waller


On Saturday, June 27, 2015 at 5:03:53 PM UTC-4, ele...@gmail.com wrote:

 Is your od program flushing its output?  Maybe its stuck in its internal 
 buffers, not in the pipe.


nah man, if it's it's od, it's not going to do that, the only thing simpler 
is cat; I suppose you could try cat.

What happens when you do something like this?

*julia **fromStream,toStream,p=readandwrite(`cat`)*

*(Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`cat`, 
ProcessRunning))*


*julia **toStream.line_buffered*

*true*


*julia **toStream.line_buffered = false*

*false*


*julia **fromStream.line_buffered = false*

*false*


*julia **write(toStream,x)*

*1*


*julia **readavailable(fromStream)*

*1-element Array{UInt8,1}:*

* 0x78*


Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-28 Thread Jameson Nash
yes, it is the fault of `od`. you can see this by using `cat` instead and
observing that it works. if you play around with the thresholds in `od`,
you will observe that it is doing block-buffering of 4096 byte chunks when
the input is a pipe.

Unless you turn on write buffering (with `buffer_writes(si)`), the `write`
function implicitly calls `flush`, and will block the task until the write
completes (the actual `flush` function is a no-op). Therefore, it's best to
call write in a separate task if you are processing both ends of the pipe:

julia (so,si,pr) = readandwrite(`od`)
(Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`od`,
ProcessRunning))

julia @async write(si,repeat(test\n,1))
Task (done) @0x7fe37aa0daa0

(note, the line_buffered property has no effect)

Note that Base.readavailable returns a random, non-zero number of bytes,
which is presumably not what you want?

julia Base.readavailable(so)
135168-element Array{UInt8,1}:
...
julia Base.readavailable(so)
61440-element Array{UInt8,1}:
...

In order to get the full output, you need to instead call:
julia close(si)
julia readall(so)


On Sun, Jun 28, 2015 at 9:08 AM Jeff Waller truth...@gmail.com wrote:



 On Saturday, June 27, 2015 at 5:03:53 PM UTC-4, ele...@gmail.com wrote:

 Is your od program flushing its output?  Maybe its stuck in its internal
 buffers, not in the pipe.


 nah man, if it's it's od, it's not going to do that, the only thing
 simpler is cat; I suppose you could try cat.

 What happens when you do something like this?

 *julia **fromStream,toStream,p=readandwrite(`cat`)*

 *(Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`cat`,
 ProcessRunning))*


 *julia **toStream.line_buffered*

 *true*


 *julia **toStream.line_buffered = false*

 *false*


 *julia **fromStream.line_buffered = false*

 *false*


 *julia **write(toStream,x)*

 *1*


 *julia **readavailable(fromStream)*

 *1-element Array{UInt8,1}:*

 * 0x78*



[julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-27 Thread Laurent Bartholdi
I'm trying to interact with an exterior program, and can't get it to work 
as I want. Let's say the program is od for example. I try:

julia (so,si,pr) = readandwrite(`od`)
(Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`od`, 
ProcessRunning))

julia write(si,repeat(test\n,100))
500
julia flush(si)
Pipe(open, 0 bytes waiting)

julia readline(so)
^C # nothing happens, the process is blocking output

How do I manage to get Julia to give me the output of od? A line was 
already ready after the first 16 characters of input.

This is related to buffering: if I stuff the buffer, then I do get lines 
asynchronously:
julia (so,si,pr) = readandwrite(`od`);
julia write(si,repeat(test\n,1));
julia readline(so)
000062564  072163  072012  071545  005164  062564  072163 
 072012\n

However, there also seems to be a bug in Julia here:
julia (so,si,pr) = readandwrite(`od`);
julia write(si,repeat(test\n,10));
# and Julia is stuck
^CERROR: InterruptException:
ERROR (unhandled task failure): write: broken pipe (EPIPE)
 in yieldto at ./task.jl:21
 in wait at ./task.jl:309
 in wait at ./task.jl:225
 in wait_full at ./multi.jl:573
 in take! at ./multi.jl:744
 in take_ref at ./multi.jl:752
 in call_on_owner at ./multi.jl:718
 in anonymous at task.jl:86

julia pr # hmmm... I wonder in which state the process is
^CERROR: InterruptException:

bash$ # Julia crashed


Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-27 Thread Miguel Bazdresch
You can make sure that there is data in `so` by looking at its 'bytes
waiting' field. If there is indeed data in the pipe, maybe there is no
newline character in it? Have you tried `readall` instead of `readline`?

-- mb

On Sat, Jun 27, 2015 at 8:45 AM, Laurent Bartholdi 
laurent.bartho...@gmail.com wrote:

 I'm trying to interact with an exterior program, and can't get it to work
 as I want. Let's say the program is od for example. I try:

 julia (so,si,pr) = readandwrite(`od`)
 (Pipe(open, 0 bytes waiting),Pipe(open, 0 bytes waiting),Process(`od`,
 ProcessRunning))

 julia write(si,repeat(test\n,100))
 500
 julia flush(si)
 Pipe(open, 0 bytes waiting)

 julia readline(so)
 ^C # nothing happens, the process is blocking output

 How do I manage to get Julia to give me the output of od? A line was
 already ready after the first 16 characters of input.

 This is related to buffering: if I stuff the buffer, then I do get lines
 asynchronously:
 julia (so,si,pr) = readandwrite(`od`);
 julia write(si,repeat(test\n,1));
 julia readline(so)
 000062564  072163  072012  071545  005164  062564  072163
  072012\n

 However, there also seems to be a bug in Julia here:
 julia (so,si,pr) = readandwrite(`od`);
 julia write(si,repeat(test\n,10));
 # and Julia is stuck
 ^CERROR: InterruptException:
 ERROR (unhandled task failure): write: broken pipe (EPIPE)
  in yieldto at ./task.jl:21
  in wait at ./task.jl:309
  in wait at ./task.jl:225
  in wait_full at ./multi.jl:573
  in take! at ./multi.jl:744
  in take_ref at ./multi.jl:752
  in call_on_owner at ./multi.jl:718
  in anonymous at task.jl:86

 julia pr # hmmm... I wonder in which state the process is
 ^CERROR: InterruptException:

 bash$ # Julia crashed



Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-27 Thread Laurent Bartholdi
Dear Miguel:
Indeed, data is not made available to the pipe; though it should be there, 
because od prints lines as soon as they're available. I tried readall, 
but it also blocks. I should have added that I tested this with the latest, 
0.4 release from github.

I also tried just reading one character, with read(so,UInt8), and this 
also blocks.

I notice that you are the author of the gnuplot package Gaston; so you 
are certainly familiar with the issue. Looking at Gaston's code, I see that 
you directly called :popen from the C library. Is there a reason not to use 
the higher-level interface of Julia?

I got more crashes by feeding large amounts of data to a pipe:

julia (so,si,pr) = readandwrite(`od`);

julia write(si,repeat(test\n,10));
^CERROR: InterruptException:Assertion failed: (req-handle == stream), 
function uv__write, file src/unix/stream.c, line 741.

signal (6): Abort trap: 6
__pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
Abort trap: 6
bash$

Thanks in advance! Laurent


Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-27 Thread Miguel Bazdresch
To answer your question about Gaston first, when I wrote that code nearly 3
years ago, there was no infrastructure in julia to create pipes to external
processes. That's why I went with popen from the C standard library. I will
update that code, but I want to read from both Gnuplot's STDOUT and STDERR
while writing to STDIN, which is not supported by Julia at the moment. I'm
trying to come up with a solution to that.

Are you sure that your process `od` is printing to STDOUT and not STDERR?

The crashes you're seeing look like worth opening an issue for, especially
if they're easy to reproduce.

-- mb

On Sat, Jun 27, 2015 at 11:49 AM, Laurent Bartholdi 
laurent.bartho...@gmail.com wrote:

 Dear Miguel:
 Indeed, data is not made available to the pipe; though it should be there,
 because od prints lines as soon as they're available. I tried readall,
 but it also blocks. I should have added that I tested this with the latest,
 0.4 release from github.

 I also tried just reading one character, with read(so,UInt8), and this
 also blocks.

 I notice that you are the author of the gnuplot package Gaston; so you
 are certainly familiar with the issue. Looking at Gaston's code, I see that
 you directly called :popen from the C library. Is there a reason not to use
 the higher-level interface of Julia?

 I got more crashes by feeding large amounts of data to a pipe:

 julia (so,si,pr) = readandwrite(`od`);

 julia write(si,repeat(test\n,10));
 ^CERROR: InterruptException:Assertion failed: (req-handle == stream),
 function uv__write, file src/unix/stream.c, line 741.

 signal (6): Abort trap: 6
 __pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
 Abort trap: 6
 bash$

 Thanks in advance! Laurent



Re: [julia-users] readandwrite: how can I read a line as soon as it's written by the process?

2015-06-27 Thread elextr
Is your od program flushing its output?  Maybe its stuck in its internal 
buffers, not in the pipe.

On Sunday, June 28, 2015 at 4:34:20 AM UTC+10, Miguel Bazdresch wrote:

 To answer your question about Gaston first, when I wrote that code nearly 
 3 years ago, there was no infrastructure in julia to create pipes to 
 external processes. That's why I went with popen from the C standard 
 library. I will update that code, but I want to read from both Gnuplot's 
 STDOUT and STDERR while writing to STDIN, which is not supported by Julia 
 at the moment. I'm trying to come up with a solution to that.

 Are you sure that your process `od` is printing to STDOUT and not STDERR?

 The crashes you're seeing look like worth opening an issue for, especially 
 if they're easy to reproduce.

 -- mb

 On Sat, Jun 27, 2015 at 11:49 AM, Laurent Bartholdi laurent@gmail.com 
 javascript: wrote:

 Dear Miguel:
 Indeed, data is not made available to the pipe; though it should be 
 there, because od prints lines as soon as they're available. I tried 
 readall, but it also blocks. I should have added that I tested this with 
 the latest, 0.4 release from github.

 I also tried just reading one character, with read(so,UInt8), and this 
 also blocks.

 I notice that you are the author of the gnuplot package Gaston; so you 
 are certainly familiar with the issue. Looking at Gaston's code, I see that 
 you directly called :popen from the C library. Is there a reason not to use 
 the higher-level interface of Julia?

 I got more crashes by feeding large amounts of data to a pipe:

 julia (so,si,pr) = readandwrite(`od`);

 julia write(si,repeat(test\n,10));
 ^CERROR: InterruptException:Assertion failed: (req-handle == stream), 
 function uv__write, file src/unix/stream.c, line 741.

 signal (6): Abort trap: 6
 __pthread_kill at /usr/lib/system/libsystem_kernel.dylib (unknown line)
 Abort trap: 6
 bash$

 Thanks in advance! Laurent