Skip to content
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

[fleche] Implement document scheduler #566

Merged
merged 1 commit into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
- Hover request can now be extended by plugins (@ejgallego, #562)
- Updated LSP and JS client libs, notably to vscode-languageclient 9
(@ejgallego, #565)
- Implement a LIFO document scheduler, this is heavier in the
background as more documents will be checked, but provides a few
usability improvements (@ejgallego, #566, fixes #563, reported by
Ali Caglayan)

# coq-lsp 0.1.7: Just-in-time
-----------------------------
Expand Down
2 changes: 1 addition & 1 deletion examples/Pff.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Require Export Even.
Require Import Psatz.

(*** was file sTactic.v ***)

Set Warnings "-deprecated-syntactic-definition".
(****************************************************************************

IEEE754 : sTactic
Expand Down
32 changes: 26 additions & 6 deletions fleche/theory.ml
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,24 @@ module Check : sig
val deschedule : uri:Lang.LUri.File.t -> unit
val maybe_check : io:Io.CallBack.t -> (Int.Set.t * Doc.t) option
end = struct
let pending = ref None
let pending = ref []

let pend_pop = function
| [] -> []
| _ :: p -> p

(** Push to front; beware of complexity here? Usually we don't have more than
10-20 files open in this use case; other use cases may require a more
efficient data-structure. *)
let pend_push uri pend = uri :: CList.remove Lang.LUri.File.equal uri pend

(** Try until [Some] *)
let rec pend_try f = function
| [] -> None
| l :: tt -> (
match f l with
| None -> pend_try f tt
| Some r -> Some r)

let get_check_target pt_requests =
let target_of_pt_handle (_, (l, c)) = Doc.Target.Position (l, c) in
Expand All @@ -191,19 +208,20 @@ end = struct
let requests = Handle.update_doc_info ~handle ~doc in
if Doc.Completion.is_completed doc.completed then Register.fire ~io ~doc;
(* Remove from the queu *)
if Doc.Completion.is_completed doc.completed then pending := None;
if Doc.Completion.is_completed doc.completed then
pending := pend_pop !pending;
Some (requests, doc)
| None ->
pending := pend_pop !pending;
Io.Log.trace "Check.check"
("file " ^ Lang.LUri.File.to_string_uri uri ^ " not available");
None

let maybe_check ~io = Option.bind !pending (fun uri -> check ~io ~uri)
let schedule ~uri = pending := Some uri
let maybe_check ~io = pend_try (fun uri -> check ~io ~uri) !pending
let schedule ~uri = pending := pend_push uri !pending

let deschedule ~uri =
if Option.compare Lang.LUri.File.compare (Some uri) !pending = 0 then
pending := None
pending := CList.remove Lang.LUri.File.equal uri !pending
end

let send_error_permanent_fail ~io ~uri ~version message =
Expand Down Expand Up @@ -355,6 +373,7 @@ module Request = struct
if Doc.Completion.is_completed doc.completed then Now doc
else (
Handle.attach_cp_request ~uri ~id;
Check.schedule ~uri;
Postpone))
| PosInDoc { uri; point; version; postpone } ->
with_doc ~uri ~f:(fun doc ->
Expand All @@ -363,6 +382,7 @@ module Request = struct
| true, _ -> Now doc
| false, true ->
Handle.attach_pt_request ~uri ~id ~point;
Check.schedule ~uri;
Postpone
| false, false -> Cancel)

Expand Down
5 changes: 3 additions & 2 deletions fleche/theory.mli
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ module Request : sig
| Postpone
| Cancel

(** Add a request to be served; returns [true] if request is added to the
queue , [false] if the request can be already answered. *)
(** Add a request to be served; returns [Postpone] if request is added to the
queue, [Now doc] if the request is available. [Cancel] means "we will
never be able to serve this" *)
val add : t -> action

(** Removes the request from the list of things to wake up *)
Expand Down
1 change: 1 addition & 0 deletions lang/lUri.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ module File = struct
let extension { file; _ } = Filename.extension file
let hash = Hashtbl.hash
let compare = Stdlib.compare
let equal = Stdlib.( = )
end
3 changes: 3 additions & 0 deletions lang/lUri.mli
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ module File : sig
(** compare *)
val compare : t -> t -> int

(** equal *)
val equal : t -> t -> bool

(** hash *)
val hash : t -> int
end
Loading