eclipse-lsp4e / eclipse-lsp4e/lsp4e
LanguageServerWrapper is not stopped on Eclipse shutdown
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 85
- Forks
- 69
- Avg merge
- 8h 33m
- Merged PRs (30d)
- 6
Description
Eclipse outputs the following error to standard error on shutdown, if any LSP-enabled editors are still opened:
Jun 04, 2023 8:12:12 PM org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer fireStreamClosed
INFO: The input stream was closed.
java.io.InterruptedIOException
at java.base/java.io.PipedInputStream.read(PipedInputStream.java:328)
at org.vgcpge.eclipse.copilot.ui.internal.OrphanPipedInputStream.read(OrphanPipedInputStream.java:21)
at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:79)
at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
The problem is caused by interruption of the MessageProducer on shutdown.
Thread [Framework stop - Equinox Container: e7e68fc9-1058-4290-853a-605fd888929e] (Suspended (breakpoint at line 670 in ThreadPoolExecutor$Worker))
owns: Object (id=178)
ThreadPoolExecutor$Worker.interruptIfStarted() line: 670
ThreadPoolExecutor.interruptWorkers() line: 769
ThreadPoolExecutor.shutdownNow() line: 1417
LanguageServerWrapper.stopDispatcher() line: 210
0x00000008013a7440.accept(Object) line: not available
CopyOnWriteArrayList<E>.forEach(Consumer<? super E>) line: 807
CopyOnWriteArraySet<E>.forEach(Consumer<? super E>) line: 425
LanguageServiceAccessor.shutdownAllDispatchers() line: 686
LanguageServerPlugin.stop(BundleContext) line: 43
BundleContextImpl$3.run() line: 875
BundleContextImpl$3.run() line: 1
AccessController.executePrivileged(PrivilegedExceptionAction<T>, AccessControlContext, Class<?>) line: 807
AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: 569
BundleContextImpl.stop() line: 867
EquinoxBundle.stopWorker0() line: 1046
EquinoxBundle$EquinoxModule.stopWorker() line: 376
EquinoxBundle$EquinoxModule(Module).doStop() line: 660
EquinoxBundle$EquinoxModule(Module).stop(Module$StopOptions...) line: 521
ModuleContainer$ContainerStartLevel.decStartLevel(int, List<Module>) line: 1893
ModuleContainer$ContainerStartLevel.doContainerStartLevel(Module, int, FrameworkListener...) line: 1768
EquinoxBundle$SystemBundle$EquinoxSystemModule(SystemModule).stopWorker() line: 275
EquinoxBundle$SystemBundle$EquinoxSystemModule.stopWorker() line: 208
EquinoxBundle$SystemBundle$EquinoxSystemModule(Module).doStop() line: 660
EquinoxBundle$SystemBundle$EquinoxSystemModule(Module).stop(Module$StopOptions...) line: 521
EquinoxBundle$SystemBundle$EquinoxSystemModule(SystemModule).stop(Module$StopOptions...) line: 207
EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run() line: 226
Thread.run() line: 833
Investigation shows, that LSP4E relies on LanguageServerWrapper to stop processing before its Executor is shutdown. However, the only way to stop processing is to call LanguageServerWrapper.stop() and that is not called on shutdown - the call is delayed too much by org.eclipse.lsp4e.LanguageServerWrapper.startStopTimer().
AFAIK, this results in forceful termination of child process without a chance for graceful shutdown.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with LanguageServerWrapper.stop(), stopDispatcher(), and startStopTimer(), then trace LanguageServiceAccessor.shutdownAllDispatchers() and LanguageServerPlugin.stop() to understand the shutdown ordering. Confirm that dispatchers stop processing before their executor is shut down, that the child process can shut down gracefully, and that Eclipse no longer emits the reported InterruptedIOException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100