librelist archives

« back to archive

Issue #957, thoughts wanted

Issue #957, thoughts wanted

From:
Jean Niklas L'orange
Date:
2013-03-06 @ 15:43
Hey guys,

I'd first of all apologize for a rather long email. For those not
interested in #957, feel free to ignore this. However, it would be lovely
if you took the time to read through it and comment on how to approach this
issue (whether I'm on right track etc).

I have been working on #957 [1] for some time now, and it seems like it's
just barely possible to solve this. I'll elaborate why shortly, but let me
first mention all the different issues related to this.

First off, a catch-up for those who hasn't worked much with this problem:
I've mentioned the different problems and solutions to the issue in a note
I wrote[2]. I also wrote about the mess related with
implementing interruptible blocks[3], though most of it is not necessary to
know: Just be aware that cancelling blocking reads is now a solved problem.

[1]: https://github.com/technomancy/leiningen/issues/957
[2]: http://www.hypirion.com/leiningen/2-0-0-blocking-issue
[3]: http://hypirion.com/musings/how-to-cancel-a-blocking-read

The path which seems most elegant is to replace System.in with
an interruptible version, and rebind *in* so that noone will attempt to
read from the original System.in. Perhaps naively I thought that most
libraries used by Leiningen could either be enhanced to accept what input
stream to read from, If they by default read from a wrapper around
Filedescriptor.in. This works nice for nREPL, but any use of
System.console().readPassword() creates a havoc as there is normally no way
to change the Console's Reader.

I've peeked and poked around in the source code for OpenJDK in the Console
implementation, and it is theoretically possible to change reader through
reflection. The main issue with this is that this will rely on
implementation-specific details and may potentially crash on very many
JVM/JDK implementations.

There are some other viable options to handle this, but my main question
now is how important it is to send EOFs to subprocesses. I'm mainly asking
because this issue has been *way* more hairy than I expected it to be, and
I'm unsure if I have enough time to solve this by the 17th of March. If
it's not that important, it would be better to not put this in the 2.1.0
milestone, and let it be a bonus if it's added in it.

I would also like some ideas on how to solve the
System.console().readPassword() case. I have some ideas, though I've not
verified that any of them work:

   - Nofix. This problem is so complex that it may either interfere with
   the stability of Leiningen or takes too much time to be worthwhile.
   - Reflection: Create a modified Reader which is used by the System
   Console to fix the issue. May impact stability on non-OpenJDK platforms.
   - Make another password reader: This would enforce all libraries used by
   Leiningen which may have to read passwords to be able to specify how the
   password is read.
   - Run all potential password reads in subprocesses. This makes Leiningen
   slower when one has to read, but hey, it may actually work properly.


All code doing dirty IO work will be put in a separate library (
https://github.com/hyPiRion/com.hypirion.io for now) so don't worry about
ugly code in Leiningen's codebase. For Leiningen itself, the code should be
pretty clean.

-- 
Regards,
Jean Niklas L'orange