-
Notifications
You must be signed in to change notification settings - Fork 396
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
[RPC] API for module build notifications #4439
Comments
/cc @cwong-ocaml |
This was discussed in the recent dune meeting. @cwong-ocaml what was the workaround used at jst? I don't recall anymore. |
I have a new proposal to solve this problem. We an rpc request that is morally equivalent to: val follow_build : [`Module_path of string] -> unit Fiber.t This call will do two things:
On the lsp side, we will loop @voodoos does this make sense to you? cc @cwong-ocaml, @jeremiedimino who were present at the meeting and were to interested in how this would work at jst. |
This sounds good. This way we offload the dependency analysis to Dune: the |
@snowleopard to implement this feature, I need some additional functionality from val on_rebuild : Path.t -> (unit -> [`Success | `Fail] Fiber.t) -> [`Unsubscribe of (unit -> unit)] But I'm open to other proposals. What do you think about this? |
@rgrinberg I can't quite understand what the second argument means. Did you mean something like this instead? val on_rebuild : Path.t -> ([`Success | `Fail] -> unit Fiber.t) -> [`Unsubscribe of (unit -> unit)] |
Assuming the above is correct, I would probably generalise it slightly, to make it easier to subscribe and unsubscribe in one go: val on_rebuild : (Path.t -> bool) -> f:(Path.t -> [`Success | `Failure] -> unit Fiber.t) -> [`Unsubscribe of (unit -> unit)] |
Yes I did.
This needs a bit of clarification for me. Is the idea to do something like: let interested_paths = ref Path.Set.empty in
let (`Unsubscribe unsub) = Build_system.on_rebuild (fun p -> Path.Set.mem !intersted_path p) ~f in
...
let on_client_open_file file = interested_paths := Path.Set.add !interested_paths file in
... So the first argument acts as a set of the paths that I'm intersted in? |
Yes, exactly. From the point of view of
|
Okay, that sounds good to me. @jeremiedimino wdyt? |
Actually, this api doesn't have a good performance profile. Consider |
That's a good point! If the API allows the user to add a subscriber only to a specific With the API that I proposed, we will need to store subscribers in a list and traverse that list on completion of every build action. This can be bad if So, yes, I can see how we can prefer one or the other depending on our assumptions about |
Given the conversation the simpler API seems fine to me. As a side note, I've seen more polymorphic variants used just as documentations creep in in recent PRs. Such as the |
Agreed about polymorphic variants: defining a separate P.S.: I just remembered that we have a cute monoid that could be used here and now I have to share this knowledge :D It's possible to do this: module Unsubscribe = Monoid.Endofunction.Left (Unit) and then use |
I'd like to propose broadening the proposed module Status : sig
type t =
| Success
| Fail of { errors : Diagnostic.t list }
| Rebuilding of { dependency_errors : Diagnostic.t list }
| Not_building (* File is not in the transitive closure of current build targets *)
end
val on_rebuild : Path.t -> (Status.t -> unit Fiber.t) -> Unsubscribe.t This can be useful beyond the LSP use case that @rgrinberg cited in his original post - we can use this to surface per-file build status indicators, for example. It's particularly helpful to know whether an issue was encountered in a dependency of the file that is preventing it from getting rebuilt so that we can jump to that location to resolve it. I'm sure there are plenty of other use cases that I'm not imagining, but generally the more information we can surface about the state of the build for a given file the more useful tooling we can build on it.' EDIT: The specific use I have in mind for build-status indicators is to know whether to unstale diagnostics and whether we can expect Merlin to work properly in the file. So if something about this API would be insufficient for those purposes, we should discuss this further before this is built. |
This issue describes a current problem with the interaction of LSP (or merlin) and dune in watch mode. It should be possible to fix this problem with RPC.
The issues is as follows:
A
andB
.B
depends onA
.A
and switches toB
.A
causes an error inB
(or the reverse, there was an error inB
and we fixed it by changingA
). However, becauseA
remains unmodified, LSP will not typecheck it again to add new errors (or dismiss stale ones).To work around this issue, I think the property we're looking forward is: whenever a user is editing some module X, dune should notify the client that X has been re-compiled. In the case of LSP, this will prompt the LSP server to type check the source of that module again and post an up to date list of errors.
We can go about it in two ways:
The first one is simpler, while the second one is more efficient. I'm inclined to go with the second one as
$ dune build @all
in a workspace with 1k modules would trigger 1k notifications. That seems excessive and 1k modules is certainly not an upper bound.The text was updated successfully, but these errors were encountered: