Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible again to read STDERR without calling cat #11919

Closed
wants to merge 4 commits into from

Conversation

Keno
Copy link
Member

@Keno Keno commented Jun 28, 2015

Merge the Pipe() and Pipe(C_NULL) constructors having the former just
call the latter and delaying initialization to the place where it is
actually needed. Now passing an empty Pipe to spawn will once again
initialize it with the appropriate pipe end. Fixes #11824.

@tkelman tkelman added the io Involving the I/O subsystem: libuv, read, write, etc. label Jun 28, 2015
@@ -1149,6 +1149,7 @@ export
ntoh,
open,
pipe,
Pipe,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kinda confusing to export this when it's a rather different thing than the pipe function

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think once processes are readable/writable, this can just be pipe() (although @vtjnash wants that to return a pair). I think maybe the right design is instead of have another method that creates the other pipe end.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe have a real API design discussion about this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd be ok with calling this pipe() and adding pipepair() in the future if necessary. Names that differ only in case are really annoying.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what does the pipe function do now then? Either connect two commands via a pipe or construct a pipe object?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keno and I both suggested that at the beginning of this thread 17 days ago.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with that is that pipe with more than one argument is a lazy constructor for a command object, while Pipe() creates a pipe object that run modifies.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might just have to be Pipe and pipeline, though I sorta dread having to tell people they have to go from one character to 8 for this functionality.

Of course, I also suggested const 🚰= Pipe

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Maybe having pipe and Pipe isn't so bad :-\

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One suggestion that I forgot to mention here was pipe and PipeEnd. I also considered Piping (as in to get data out of your pipeline, just add some Piping).

@@ -311,7 +311,9 @@ macro setup_stdio()
in,out,err = stdios
if isa(stdios[1], Pipe)
if stdios[1].handle == C_NULL
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder (this should be using the test isopen(stdios[1]), now that we have that field)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per our discussion, the C_NULL here should be fine as this way you get an error in the use-after-close case whereas otherwise it would silently pass /dev/null.

@Keno Keno force-pushed the kf/stderrpipe branch 2 times, most recently from 9f74adf to caefce9 Compare July 14, 2015 22:30
@tkelman
Copy link
Contributor

tkelman commented Jul 14, 2015

spawn test looks stuck on win32 and win64 appveyor

also ref https://github.com/JuliaLang/julia/pull/11919/files#r33425946

@Keno
Copy link
Member Author

Keno commented Jul 17, 2015

Renamed pipe to pipeline. I'm planning a whole documentation overhaul, but given that the doc transition has yet to happen, I haven't touched docs at all. Once that's done I'll do docs.

@JeffBezanson
Copy link
Member

Hmm, still times out in CI.

@Keno
Copy link
Member Author

Keno commented Jul 28, 2015

Yeah, I'll take a look.

@ViralBShah ViralBShah added the priority This should be addressed urgently label Aug 14, 2015
Keno added 2 commits August 16, 2015 17:59
Merge the Pipe() and Pipe(C_NULL) constructors having the former just
call the latter and delaying initialization to the place where it is
actually needed. Now passing an empty Pipe to spawn will once again
initialize it with the appropriate pipe end.
@Keno
Copy link
Member Author

Keno commented Aug 18, 2015

FWIW, I found the broken test, but the spawn test is still hanging on windows. Could somebody who has a running windows install test what exactly is broken there?

@test readall(pipe(`$exename -f -e 'println(STDERR,"Hello World")'`, stderr=`cat`)) == "Hello World\n"
@test readall(pipeline(`$exename -f -e 'println(STDERR,"Hello World")'`, stderr=`cat`)) == "Hello World\n"
p = Pipe()
run(pipeline(`$exename -f -e 'println(STDERR,"Hello World")'`, stderr = p))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem i have with this API is that it looks like you could use p repeated to aggregate the stderr for many processes, but in fact you can't even call run twice on this Cmd object, since run mutates the p object when it opens it. What is the disadvantage to making Pipe refer to the entire pipe, while adding an internal type that represents just one end of the pipe (e.g. what is called Pipe in this PR)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is similar to what I proposed at some point – the idea was that a Pipe object would be similar to a cat process but without any process, just going through the kernel.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use spawn not run here to avoid forcing the kernel to buffer the output (the windows kernel is forcing the process to stay alive until there is a reader for the stderr pipe causing the hang on appveyor).

will push a fix shortly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's an even better example of why we should never export PipeEnd to the user:

p = PipeEnd()
spawn(pipeline(`foo` & `bar`, stdout=p)) # this expression has undefined behavior, since bar may get the wrong end of the pipe

(i'm most of the way done with a cleanup effort to add a Pipe object which tracks a pair of pipe ends)

@Keno Keno assigned vtjnash and unassigned Keno Aug 19, 2015
@vtjnash vtjnash closed this Aug 21, 2015
@vtjnash vtjnash deleted the kf/stderrpipe branch August 27, 2015 04:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
io Involving the I/O subsystem: libuv, read, write, etc. priority This should be addressed urgently
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants