You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The client includes a .work_done_progress_params.work_done_token field in the "params" given to the server.
The server sends back $/progress begin/report/end notifications to the client using this work_done_token value.
Implementation
To support this type of $/progress, we should do the following:
Introduce a Client::progress() method resembling the draft proposal below. This lets the server send a stream of $/progress notifications to the client using a client-issued WorkDoneToken.
Draft API
implClient{pubfnprogress<T>(&self,token:ProgressToken,title:T) -> ProgresswhereT:Into<String>,}enumBounded{}enumUnbounded{}enumCancellable{}enumNotCancellable{}pubstructProgress<B = Unbounded,C = NotCancellable>{ ... }impl<C>Progress<Unbounded,C>{pubfnbounded(self,start_percentage:u32) -> Progress<Bounded,C>;}impl<B>Progress<B,NotCancellable>{pubfncancellable(self,show_cancel_btn:bool) -> Progress<B,Cancellable>;}impl<B,C>Progress<B,C>{pubfnwith_message<M>(self,message:M) -> SelfwhereM:Into<String>;pubasyncfnbegin(self) -> OngoingProgress<B,C>;}pubstructOngoingProgress<B,C>{ ... }implOngoingProgress<Unbounded,NotCancellable>{pubasyncfnreport<M>(&self,message:M)whereM:Into<Option<String>>;}implOngoingProgress<Unbounded,Cancellable>{pubasyncfnreport<M>(&self,message:M,show_cancel_btn:bool)whereM:Into<Option<String>>;}implOngoingProgress<Bounded,NotCancellable>{pubasyncfnreport<M>(&self,percentage:u32,message:M)whereM:Into<Option<String>>;}implOngoingProgress<Bounded,Cancellable>{pubasyncfnreport<M>(&self,percentage:u32,message:M,show_cancel_btn:bool)whereM:Into<Option<String>>;}impl<C>OngoingProgress<Bounded,C>{// This is explicitly allowed by the official specification. Clients will treat all// subsequent calls to `report()` as unbounded progress.pubfndiscard_bound(self) -> OngoingProgress<Unbounded,C>;}impl<B,C>OngoingProgress<B,C>{pubfntoken(&self) -> &ProgressToken;pubasyncfnfinish<M>(self,message:M)whereM:Into<Option<String>>;}
Usage
implLanguageServerforMyServer{asyncfncompletion(&self,params:CompletionParams) -> Result<Option<CompletionResponse>>{let token = params.work_done_progress_params.work_done_token.unwrap();let progress = self.client.progress(token,"retrieving completions").bounded(0).with_message("starting work...").begin().await;for x in something {// Do some work...let percentage = ...progress.report(percentage,"reticulating splines".to_owned()).await;}
progress.finish("done!".to_owned()).await;// ...}// ...}
Other Ideas
Consider dropping the message: M where M: Into<Option<String>> argument in favor of distinct .foo() and .foo_with_message() methods.
Consider separate methods for bounded/unbounded × cancellable/not-cancellable instead of a typed builder.
Seems like this would get messy quickly, but will still list it here as an option.
Consider the implications of the Bounded, Unbounded, Cancellable, NotCancellable enums being public vs. private.
For bounded progress reports: consider requiring users to pass an increment value instead of a percentage. This ensures the percentage values sent to the client are monotonic.
For bounded progress reports: consider how percentage values above 100% should be handled. Panic? Log a warning? Something else?
For cancellable progress reports: consider alternatives to the show_cancel_btn: bool argument:
Use an enum with explicit states instead of a plain bool to improve readability at the callsite?
Store the bool as a struct field and expose getters and setters instead of providing the value with every call to report()?
Nice to have: include an API for wrapping an arbitrary std::iter::Iterator and/or futures::Stream and emit a stream of progress. See indicatif::ProgressBarIter for prior art.
The text was updated successfully, but these errors were encountered:
Background
This task was split from #176.
According to the relevant section in the specification, client initiated progress is defined as follows:
.work_done_progress_params.work_done_token
field in the"params"
given to the server.$/progress
begin/report/end notifications to the client using thiswork_done_token
value.Implementation
To support this type of
$/progress
, we should do the following:Client::progress()
method resembling the draft proposal below. This lets the server send a stream of$/progress
notifications to the client using a client-issuedWorkDoneToken
.Draft API
Usage
Other Ideas
message: M
whereM: Into<Option<String>>
argument in favor of distinct.foo()
and.foo_with_message()
methods.Bounded
,Unbounded
,Cancellable
,NotCancellable
enums being public vs. private.increment
value instead of apercentage
. This ensures thepercentage
values sent to the client are monotonic.percentage
values above 100% should be handled. Panic? Log a warning? Something else?show_cancel_btn: bool
argument:bool
to improve readability at the callsite?bool
as a struct field and expose getters and setters instead of providing the value with every call toreport()
?std::iter::Iterator
and/orfutures::Stream
and emit a stream of progress. Seeindicatif::ProgressBarIter
for prior art.The text was updated successfully, but these errors were encountered: