-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remodel service as bidirectional stream #177
Comments
There may need to be some investigation as to whether most available |
@ebkalderon this seems reasonable! This is basically what http based tower services do, where we have a Body type that is basically a Stream. Usuaully, the impact middleware have is on making the connection. We can't reliably retry say a streaming request because we don't know at which state we drained the stream. But we can retry on things like we failed to make the initial request etc. Or the whole request failed with this status retry. |
This abstraction is a little bit cleaner since it hides the concept of invalid requests from the user. Additionally, it simplifies the logic in the `Service::call` trait method implementation on `LspService`. This commit is an early step towards refactoring the service model: #177
This abstraction is a little bit cleaner since it hides the concept of invalid requests from the user. Additionally, it simplifies the logic in the `Service::call` trait method implementation on `LspService`. This commit is an early step towards refactoring the service model: #177
This abstraction is a little bit cleaner since it hides the concept of invalid requests from the user. Additionally, it simplifies the logic in the `Service::call` trait method implementation on `LspService`. This commit is an early step towards refactoring the service model: #177
I wonder whether this ticket should be closed due to #313? I ended up not taking this approach with my refactoring, since it would render the vast majority of
In short, Of course, there's no support for request batching under this data model because the current version of the Language Server Protocol does not support it (microsoft/language-server-protocol#988). This is despite LSP being based, at least partially, on JSON-RPC 2.0, which does have request batching built into the specification. |
After giving it some more thought, I feel that the new design introduced by #313 should sufficiently resolve most of the concerns outlined in this ticket, while keeping the unary design. Further improvements could potentially be made on the |
Problem statement
Currently,
LspService
adopts a unary request/response model where<LspService as tower::Service>::call()
accepts a singleIncoming
message and sends anOption<String>
response back.The basic service definition looks like this:
This model is a poor fit for a Language Server Protocol implementation for several reasons:
LspService
when there really shouldn't be one, leading to hacks such asMessageStream
and wrapping each outgoing message in anOption
to get the behavior we want.LspService::call()
method. This method must be called repeatedly in order to drive both independent streams of communication, which feels awkward to use and write tests for.Proposal
For these reasons, I believe it would be better to adopt a bidirectional model structured like this:
With the above model, the
call()
method is only ever called once by the client, given a stream of incoming messages, producing a future which either resolves toOk(MessageStream)
if all is well, or anErr(ExitedError)
if the language server has already shut down. Both message streams can then be polled independently from each other, in either direction, with no strict ordering. When the language server shuts down, the outgoing message stream will terminate and any subsequent attempt to callLspService::call()
to produce a new one will immediately returnErr(ExitedError)
.User impact
This change would have a minor impact on users which rely on
tower_lsp::Server
to route communication overstdio
. It will result in a slightly different initialization process:Before
After
This change would have a greater effect on users wrapping
LspService
intower
middleware in their own projects, since the service request and response types would have changed and would need to be handled differently.The text was updated successfully, but these errors were encountered: