tools.nrepl

Sometimes *err*/*out*/value messages are surprisingly ordered

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code

Description

As described here: https://github.com/technomancy/leiningen/issues/631, the *out*, *err*, and value printing are ordered differently than expected sometimes.

There are 2 things left here:
(1) The return value can sometimes print before synchronous prints to err/out. Synchronizing all the printing on the REPLy side doesn't seem to help. An example case:

=> (do (.print *err* "one") (print "two") (print "three"))
niltwothreeone

(2) Calling .println() on the *out*/*err* streams doesn't necessarily flush the stream. Changing this may have performance/network ramifications, but generally it seems like surprising behavior. An example case:

user=> (do (.println *out* "one") (.print *err* "two") (.print *err* "three") 1)
twothreeone
1

I'd expect two .print() calls to different streams to have undefined ordering, but the other orderings were all surprising.

The attached patch forces flushes to avoid both of these, for (1) immediately before sending the value message, and for (2) on the "normal" PrintStream [autoFlush] cases of println, printf, or format.

Side note: I couldn't get any tests to fail in this scenario, even after doing some reworking of the streams used in tests, but I kept one new test in this patch anyway. Turns out it's hard to write tests that really make sure .flush() gets called.

Activity

Chas Emerick made changes -
Field Original Value New Value
Resolution Completed [ 1 ]
Status Open [ 1 ] Closed [ 6 ]

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: