8000 Exception handling in sys.process by som-snytt · Pull Request #7362 · scala/scala · GitHub
[go: up one dir, main page]

Skip to content

Exception handling in sys.process #7362

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

Merged
merged 7 commits into from
Nov 26, 2018
Merged

Conversation

som-snytt
Copy link
Contributor
@som-snytt som-snytt commented Oct 23, 2018
Handle bad process start and lazily

Improve handling of failure of a process
to start. In a `CompoundProcess`, catch
exceptions and set a special exit value.
For `lazyLines`, also supply a value so
that requesting thread doesn't hang.

It would be nicer to stow the exception
and rethrow instead of using special
integers.

Test for stale thread.

Fixes scala/scala-dev#566

@scala-jenkins scala-jenkins added this to the 2.13.0-RC1 milestone Oct 23, 2018
@som-snytt som-snytt changed the title Issue/sd 566 Exception handling in sys.process Oct 23, 2018
@som-snytt som-snytt requested a review from NthPortal October 23, 2018 00:16
@som-snytt som-snytt added the WIP label Oct 23, 2018
@NthPortal
Copy link
Contributor

@som-snytt I am flattered that you think I know anything about this

@som-snytt som-snytt removed the WIP label Oct 23, 2018
@som-snytt
Copy link
Contributor Author

@NthPortal A PR is the best place to share our lack of knowledge.

@SethTisue
Copy link
Member
SethTisue commented Oct 23, 2018

@SethTisue
Copy link
Member

the Jenkins run is green. let's see if anyone takes an interest in reviewing this. I don't know this code at all

@som-snytt
Copy link
Contributor Author

@SethTisue maybe spin off the module now? I'd volunteer to manage it a la scala-xml.

@SethTisue
Copy link
Member
SethTisue commented Oct 24, 2018

wow, really?

Adriaan and I had given up, at this point, on the idea of making more modules for 2.13, but that was because it looked like it wasn't going to happen unless someone from the core team did it.

But with 2.13.0-RC1 now pushed out a bit, if you want to go ahead and do it, I'd be in favor. Obviously you'd have our help and support, both with the splitting (which I think would be a pretty straightforward copy-and-paste job), and with helping to drum up additional help from the community once the module has been made.

@adriaanm wdyt? too late, or not?

@SethTisue
Copy link
Member
SethTisue commented Oct 24, 2018

looking over those other tickets/threads, I don't see any explicit discussion of scala.sys.process being its own module, separate from the rest of scala.sys. but actually, I was already tentatively assuming that, as was @som-snytt, apparently. sys.process is clearly a coherent unit, while the rest of scala.sys is a grab bag. so I think making a scala-process module and leaving the rest of scala.sys alone for now would make sense for 2.13.

@som-snytt
Copy link
Contributor Author

The other module could be called "better-properties".

Copy link
Member
@lrytz lrytz left a comment

Choose a reason for hiding this comment

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

running out of steam reviewing this, so much indirection in that module...

@@ -39,9 +39,10 @@ object Test {
val reading = new CountDownLatch(1)
val count = new AtomicInteger
def counted = count.get
val command = s"${f.getAbsolutePath} -classpath ${javaClassPath} Test data"
val outdir = s"$userDir/test/files/run/t6488-run.obj"
val command = s"${f.getAbsolutePath} -classpath ${javaClassPath}${pathSeparator}${outdir} Test data"
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to manually add the outdir now, but it was not necessary before?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No idea. I forgot my Indiana Jones archaeology hat. I could investigate when the windows build started failing.

Copy link
Member

Choose a reason for hiding this comment

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

Ah I didn't get the sequence of events. The broken test on windows made you discover the underlying bug. After fixing that, you still fix the test.

Though on non-windows, the manual outdir is not necessary right? Maybe there's a bug in scala.util.Properties.javaClassPath? Maybe the test should run in a forked vm?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, I still don't know. I'd assumed it was the /bin/ls fallback exec that worked on linux, but no, it should have run java with a no such class output. I recall that windows will block if i/o streams aren't consumed, was that the platform difference?

8000

Copy link
Member

Choose a reason for hiding this comment

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

Guess what println(f) shows? C:\Program Files\Java\jdk1.8.0_152\jre\bin\java-rmi.exe :-) Anyway, that's not the issue.

The test out dir is missing from the classpath indeed, on linux and windows, so the test never reaches the data() part, but that doesn't really matter, as there just needs to be some output, and the process produces Error: Could not find or load main class Test.

I still don't see why it would hang on windows not on linux, maybe you do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now that the Red Sox have clinched it, I'll find time to try it out on Windows. I bought a replacement Windows box a year ago to use for work, but I dread turning it on. I did wonder what exe the test was finding.

My previous comment about windows process blocking if out or err is not consumed is due to this happening to me in a unit test in 2003. That might have been blocking due to hitting a buffer limit, though.

It would be nice to have a words"" interpolator that uses CommandLineParser to split parts and takes args whole to render a Seq[String].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

retronym mentioned caveats at the commit to run tests in-process: 3b93517

(I missed the change at the old repo, so by now, I haven't yet thought about all the implications for tests.)

FSR, listing the obj directory fails when running in-process, after working around "partest.output" not set the same when in-process. However, forcing the test to fork makes it work.

It would be nicer if env was same for in/out-of-process. I'll try to get back to the mystery of why .obj is not listable, since compiler output is the same, it's not a virtual dir like in REPL, right?

@SethTisue
Copy link
Member
SethTisue commented Oct 26, 2018

re: the question of spinning off the module for 2.13, we discussed it internally and the conclusion was "sorry, feature freeze". there's a lot more to say than that, I have a bunch of notes on it, I'll write more soon, stand by.

(@som-snytt, you might consider whether you're interested in working on making pulling libraries into the REPL easier, a la Ammonite? does that appeal? we could discuss further on
https://contributors.scala-lang.org/t/modularization-of-scala-2-13-standard-library/635. let's return this PR to its original narrower focus.)

@som-snytt
Copy link
Contributor Author

@lrytz Thanks, reviewing is thankless. We discussed this at the office a propos this pr. I spent some time with this over the weekend, because I'd already done the crossword. This code has limited shelf-life, so no point spending time on it, but it was also my fault for approving the previous change to catch exceptions.

@som-snytt
Copy link
Contributor Author

@SethTisue no problem, it was just a thought so @lrytz wouldn't spend time reviewing it. He's too nice.

I have a jline3 branch to get back to, then I'll try more ammonization of REPL.

@lrytz
Copy link
Member
lrytz commented Oct 26, 2018

@som-snytt how confident are you in the fix? Sorry, hard question :-)

@som-snytt
Copy link
Contributor Author

@lrytz I really like the part where the threads get names you can read in a thread dump.

This really just adjusts the previous fix for catching failure on start, by moving the catch up to compound level. Otherwise an i/o thread is started after the failure. The other fix is to the previous lazy lines business, to avoid hanging after failure. So both changes are confident improvements.

@som-snytt
Copy link
Contributor Author

@adriaanm @SethTisue for the purposes of semantics, modularization is not a feature, so a feature freeze would not apply. Did you notice David Freese in the world series? My joke was the cold should not bother him, because he is Mr Freese.

@@ -39,9 +39,10 @@ object Test {
val reading = new CountDownLatch(1)
val count = new AtomicInteger
def counted = count.get
val command = s"${f.getAbsolutePath} -classpath ${javaClassPath} Test data"
val outdir = s"$userDir/test/files/run/t6488-run.obj"
val command = s"${f.getAbsolutePath} -classpath ${javaClassPath}${pathSeparator}${outdir} Test data"
Copy link
Member

Choose a reason for hiding this comment

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

Guess what println(f) shows? C:\Program Files\Java\jdk1.8.0_152\jre\bin\java-rmi.exe :-) Anyway, that's not the issue.

The test out dir is missing from the classpath indeed, on linux and windows, so the test never reaches the data() part, but that doesn't really matter, as there just needs to be some output, and the process produces Error: Could not find or load main class Test.

I still don't see why it would hang on windows not on linux, maybe you do?

@SethTisue
Copy link
Member

@adriaanm @SethTisue for the purposes of semantics, modularization is not a feature, so a feature freeze would not apply.

I tried that argument, it didn't work on Mr. Adriaan Freeze, aka the Snow Miser:

screen shot 2018-11-03 at 6 37 04 pm

@dwijnand
Copy link
Member
dwijnand commented Nov 5, 2018

@adriaanm @SethTisue for the purposes of semantics, modularization is not a feature, so a feature freeze would not apply.

I tried that argument, it didn't work on Mr. Adriaan Freeze, aka the Snow Miser:

Given writing code is introducing bugs, removing code is removing bugs. So it would be a bug fix, which are always very welcome. :trollface:

@SethTisue
Copy link
Member
SethTisue commented Nov 6, 2018

@SethTisue
Copy link
Member

Jenkins is green

the only unresolved thing I can find above is Lukas's comment at
#7362 (comment), @som-snytt is there anything further to be said there...?

PipeThreads also have names.
Improve handling of failure of a process
to start. In a `CompoundProcess`, catch
exceptions and set a special exit value.
For `lazyLines`, also supply a value so
that requesting thread doesn't hang.

It would be nicer to stow the exception
and rethrow instead of using special
integers.

Test for stale thread.
@som-snytt som-snytt force-pushed the issue/sd-566 branch 2 times, most recently from d7be37e to 2c6cd6a Compare November 11, 2018 22:09
Add contributed hello, world test,
tweaked, with fix, which partially reverts
a previous change that broke coordination
between sequential process and its pipe.
@SethTisue
Copy link
Member

@SethTisue SethTisue merged commit 738b112 into scala:2.13.x Nov 26, 2018
@SethTisue
Copy link
Member

thank you, Som, for your careful attention to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants
0