Skip to content

Corrupted state when JSON write fails #41

@ferdinand-beyer

Description

@ferdinand-beyer

I've encountered a tricky situation when a request result is not JSON serializable. While this is definitely a programmer's mistake, this unfortunately leads into a situation where the LSP server stops working.

I'm working with VS-Code as a Language Client. After a request, the client reported:

Connection to server got closed. Server will restart.

Then the client spun up a new server process. The old process was still alive, the JVM up, and my REPL connected. It was somewhat tricky to diagnose what happened.

I tracked this down to the lsp4clj.io-chan/output-stream->output-chan, which connects an async channel with a OutputStream like this:

(let [output (io/output-stream output)
        messages (async/chan 1)]
    (async/thread
      (with-open [writer output] ;; close output when channel closes
        (loop []
          (when-let [msg (async/<!! messages)]
            (write-message writer msg)
            (recur)))))
    messages)

When write-message fails, because the message is not serializable, an exception is thrown. This code then stops consuming the channel and closes the OutputStream through with-open. The client then assumes the server died, and will spin up a new one.

However, the messages channel will not be closed and will no longer be consumed. That means that the server process will continue to run, and probably hang very soon because of backpressure from the blocked output channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions