Skip to content
This repository has been archived by the owner on Dec 21, 2021. It is now read-only.

Is there an up to date example on how to use ls-api? #58

Closed
bruno-medeiros opened this issue Sep 29, 2016 · 11 comments
Closed

Is there an up to date example on how to use ls-api? #58

bruno-medeiros opened this issue Sep 29, 2016 · 11 comments

Comments

@bruno-medeiros
Copy link
Contributor

https://github.com/TypeFox/lsp4j-example seems very out of date , it uses a lot of deprecated code.
http://typefox.io/the-language-server-protocol-in-java also refers to deprecated code (JsonBasedLanguageServer and LanguageServerToJsonAdapter)

@svenefftinge
Copy link
Member

Are you looking for client side or server side example?

@bruno-medeiros
Copy link
Contributor Author

Client side.
I've been looking at https://github.com/eclipselabs/eclipse-language-service/blob/990a8ea79b6f14dc2c280dffe02b3e5fa0a962c2/org.eclipse.languageserver/src/org/eclipse/languageserver/ProjectSpecificLanguageServerWrapper.java#L175 for an example, but I don't know how correct, or canonical it is. For example I don't understand the purpose of ConcurrentMessageReader , it's not quickly obvious.

@bruno-medeiros
Copy link
Contributor Author

cc @mickaelistria
The eclipse-language-servicer code is actually an example actually of something that I suspect could be incorrect. See this code:

ExecutorService executorService = Executors.newCachedThreadPool();

...

ConcurrentMessageReader multiThreadReader = new ConcurrentMessageReader(baseMessageReader, executorService);

The ConcurrentMessageReader is initizalized with a multi-thread executor, which, from my understanding means the json-rpc requests can be handled out of order. I wonder if this is correct for the client? The client doesn't receive many requests (mostly just responses) so it might be okay for a client - but it certainly would be incorrect for the server to handle things this way, if anything, because of the text buffer modifying operations. If you execute those out of order, the text buffer model of the language server will not match the IDE / client.

@mickaelistria
Copy link
Contributor

mickaelistria commented Sep 30, 2016

I did try with Executors.singleThreadExecution() but this was freezing Eclipse (I guess because ls-api needs at least 2 threads, one for input and the other for output, so a single thread causes a deadlock).

The JSON-RPC protocol has in messages an incremental ID of a request/response to easily match them. I guess it's also used internally to make sure all operations are performed in the right order. ie if instruction 7 arrives before instruction 6, the server may decide to wait for completion of instruction 6 to run number 7...

@bruno-medeiros
Copy link
Contributor Author

bruno-medeiros commented Sep 30, 2016

@mickaelistria Have you tried passing an Executors.newCachedThreadPool() to LanguageClientEndpoint, but passing a Executors.newSingleThreadExecutor() to ConcurrentMessageReader? That might achieve the correct behavior: will provide 2 threads to JSON-RPC, but only one for handling requests.

JSON-RPC has an ID field, but JSON-RPC does not specifiy anything about ordering, that is up to actual app protocol layer. JSON-RPC only specifies that a response ID must match request ID, that's it.

It's LSP itself that specifies that requests must be handled in order: microsoft/language-server-protocol#12 , howerver I doesn't mention anything about the ID field of the request, so the ID is not meant to be used for the ordering, from what I understand. It has to be the actual order received.

I think the API of ls-api should change with regards to the constraints above. For example, if LanguageClientEndpoint does requires 2 threads, it shouldn't receive a ExecutorService since that can be single-threaded. There is not even an API in ExecutorService to check number of threads available. So LanguageClientEndpoint at most it should receive an optional ThreadFactory. The API around ConcurrentMessageReader should change somehow as well.

@mickaelistria
Copy link
Contributor

@mickaelistria Have you tried passing an Executors.newCachedThreadPool() to LanguageClientEndpoint, but passing a Executors.newSingleThreadExecutor() to ConcurrentMessageReader?

Nope, I tried several things and stopped once I got something working ;)

@bruno-medeiros
Copy link
Contributor Author

Nope, I tried several things and stopped once I got something working ;)

Hence why it would be good to have an up-to-date official example 😅

@spoenemann
Copy link
Member

Yes, that would be good. Currently the head revision of ls-api is being verified as initial contribution for lsp4j. You can track the state of the IP review here:
http://dev.eclipse.org/ipzilla/show_bug.cgi?id=12064

I'd like to wait until the code transfer is finished before we update the documentation, since the namespace of all packages is going to be changed. Please be patient...

@mickaelistria
Copy link
Contributor

mickaelistria commented Oct 17, 2016

@spoenemann And even without official documentation, what is the right executors to specify for a client? I've got some cases (VSCode-CSS) for which LSP4J gives me a timeout independently of how long I wait and the MessageTracer.onRead is called just upon timeout with apparently correct values. I guess this could be caused by wrong executors.
The exact same code on VSCode-JSON works fine. Or even the completion works fine in some parts of CSS (after a color). Any hint? Do you think it's related to executors?

@spoenemann
Copy link
Member

No idea. Sadly I won't have time for a deeper look into this until November due to the upcoming EclipseCon.

@svenefftinge
Copy link
Member

For LSP4J which is going to replace ls-api I started writing documentation here :
https://github.com/TypeFox/ls-api/blob/lsp4j/HowTo.md
We should extend and improve it as needed.

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

No branches or pull requests

4 participants