-
Notifications
You must be signed in to change notification settings - Fork 459
Allow concurrent build with RPC server #11712
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
Allow concurrent build with RPC server #11712
Conversation
4b4630c to
e7751bb
Compare
Leonidas-from-XIV
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a very nice feature. I know it has some limitations (e.g. can't build in a different profile) but I was glad to see that the target can be specified and I think that covers 80% of all usecases.
It would be nice to have tests that show this mechanism working.
bin/build_cmd.ml
Outdated
| Printf.printf | ||
| "Error: %s\n%!" | ||
| (Dyn.to_string (Dune_rpc_private.Response.Error.to_dyn error)) | ||
| | Ok Success -> print_endline "Success" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just print_endline? In case of success I mostly expect Dune to stay silent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should actually be using Dune_console. Otherwise it would break the TUI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed it to use Dune_console for now, but I don't feel strongly about changing it to not output anything on success either.
bin/build_cmd.ml
Outdated
| Console.print_user_message main); | ||
| User_error.raise | ||
| [ (match List.length errors with | ||
| | 0 -> Pp.textf "Build failed." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this a Code_error?
bin/build_cmd.ml
Outdated
| run_build_command ~common ~config ~request | ||
| match Dune_rpc_client.Where.get () with | ||
| | Some where -> | ||
| Scheduler.go_without_rpc_server ~common ~config (fun () -> build_rpc where targets) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems weird to call a function go_without_rpc_server that calls build_rpc. Maybe build_rpc should be build_remote to clarify that the build is happening on the far end of the RPC connection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to build_via_rpc_server and added some clarifying comments.
bin/build_cmd.ml
Outdated
| Target.interpret_targets (Common.root common) config setup targets | ||
| in | ||
| run_build_command ~common ~config ~request | ||
| match Dune_rpc_client.Where.get () with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this how we determine whether the build is happening locally or remotely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Clarified with a comment.
| ;; | ||
|
|
||
| let go ~common ~config f = | ||
| let f = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this to with_rpc to emphasize that this wrapper function will actually enable RPC?
| "Error: %s\n%!" | ||
| (Dyn.to_string (Dune_rpc_private.Response.Error.to_dyn error)) | ||
| | Ok Success -> print_endline "Success" | ||
| | Ok (Failure _) -> print_endline "Failure" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failures should presumably not be printed to stdout?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe but I'm not so sure. This code was just refactored in this PR, not added. dune rpc build is not a very user-friendly command (e.g. it needs to be passed sexps on the command-line) so my assumption is that it's intended to be called from scripts. As such it's not unreasonable to expect that scripts would expect the status of the build to be printed to stdout for ease of parsing.
bin/rpc/build.ml
Outdated
| let+ response = build_sexp_string_targets ~wait ~targets where in | ||
| match response with | ||
| | Error (error : Dune_rpc_private.Response.Error.t) -> | ||
| Printf.printf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably go to stderr or even use User_error or something?
| (** Sends a command to an RPC server to build the specified targets and wait | ||
| for the build to complete or fail. *) | ||
| val build | ||
| : wait:bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the wait argument to wait for the result or to wait for the connection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the connection. I've added that info to the doc comment.
| let open Conv in | ||
| let from { main; related } = main, related in | ||
| let to_ (main, related) = make ~main ~related in | ||
| let main = field "main" (required User_message.sexp_without_annots) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why sexp_without_annots here? What are annots?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarified with a doc comment on the sexp_without_annots function.
4b01bdc to
4fe5dbf
Compare
Added a test. |
|
Looks like this change has made some of our rpc tests flaky. Investigating... |
4f51f49 to
5753bdf
Compare
|
The problem was that I moved |
|
Ah looks like something else isn't working now. |
|
There's a non-deterministic crash with this error: The loc it points to is: let update_build_progress_exn ~f =
let current = Svar.read t in
match current with
| Building current -> Svar.write t @@ Building (f current)
| _ -> assert false (* <------ *)
;;I wonder if this is a race between a rebuild by the eager watch server in response to a file change and a build due to an rpc build request. Will investigate more tomorrow. |
Allow the `dune build` command to be run concurrently with an RPC server (in either passive or eager watch mode). This works by having the second instance of dune send RPC build command to the RPC server, and the RPC server then sends diagnostic messages back to the first instance of dune. Currently this is only implemented for the `dune build` command, and promoting changes into source files is not supported. There are also some subtle differences between the output of `dune build` is performing the build itself and when it's acting as an RPC client, such as file paths being absolute rather than relative and the underline under code errors losing its color. Signed-off-by: Stephen Sherratt <stephen@sherra.tt>
This function evaluates a fiber concurrently with an RPC server, so renaming to clarify this fact. Signed-off-by: Stephen Sherratt <stephen@sherra.tt>
Signed-off-by: Stephen Sherratt <stephen@sherra.tt>
Signed-off-by: Stephen Sherratt <stephen@sherra.tt>
5753bdf to
a59bb63
Compare
This turned out to be the issue. I've fixed this but now it looks like it's getting stuck running tests. I can't reproduce locally but I'll try setting up a VM with a single core in case that makes the difference. |
c11e179 to
a59bb63
Compare
This issue seems to have gone away on its own? Maybe I needed to be more patient... |
CHANGES: ### Fixed - Fixed a bug that was causing cram tests attached to multiple aliases to be run multiple times. (ocaml/dune#11547, @Alizter) - Fix: pass pkg-config (extra) args in all pkgconfig invocations. A missing --personality flag would result in pkgconf not finding libraries in some contexts. (ocaml/dune#11619, @MisterDA) - Fix: Evaluate `enabled_if` when computing the stubs for stanzas such as `foreign_library` (ocaml/dune#11707, @Alizter, @rgrinberg) - Fix $ dune describe pp for libraries in the presence of `(include_subdirs unqualified)` (ocaml/dune#11729, fixes ocaml/dune#10999, @rgrinberg) - Fix `$ dune subst` in sub directories of a git repository (ocaml/dune#11760, fixes ocaml/dune#11045, @Richard-Degenne) - Fix a crash involving `Path.drop_prefix` when using Melange on Windows (ocaml/dune#11767, @nojb) ### Added - Added detection and warning for common typos in package dependency constraints (ocaml/dune#11600, fixes ocaml/dune#11575, @kemsguy7) - Added `(extra_objects)` field to `(foreign_library)` stanza with `(:include)` support. (ocaml/dune#11683, @Alizter) ### Changed - Allow build RPC messages to be handled by dune's RPC server in eager watch mode (ocaml/dune#11622, @gridbugs) - Allow concurrent build with RPC server (ocaml/dune#11712, @gridbugs)
CHANGES: ### Fixed - Fixed a bug that was causing cram tests attached to multiple aliases to be run multiple times. (ocaml/dune#11547, @Alizter) - Fix: pass pkg-config (extra) args in all pkgconfig invocations. A missing --personality flag would result in pkgconf not finding libraries in some contexts. (ocaml/dune#11619, @MisterDA) - Fix: Evaluate `enabled_if` when computing the stubs for stanzas such as `foreign_library` (ocaml/dune#11707, @Alizter, @rgrinberg) - Fix $ dune describe pp for libraries in the presence of `(include_subdirs unqualified)` (ocaml/dune#11729, fixes ocaml/dune#10999, @rgrinberg) - Fix `$ dune subst` in sub directories of a git repository (ocaml/dune#11760, fixes ocaml/dune#11045, @Richard-Degenne) - Fix a crash involving `Path.drop_prefix` when using Melange on Windows (ocaml/dune#11767, @nojb) ### Added - Added detection and warning for common typos in package dependency constraints (ocaml/dune#11600, fixes ocaml/dune#11575, @kemsguy7) - Added `(extra_objects)` field to `(foreign_library)` stanza with `(:include)` support. (ocaml/dune#11683, @Alizter) ### Changed - Allow build RPC messages to be handled by dune's RPC server in eager watch mode (ocaml/dune#11622, @gridbugs) - Allow concurrent build with RPC server (ocaml/dune#11712, @gridbugs)
Allow the
dune buildcommand to be run concurrently with an RPC server (in either passive or eager watch mode). This works by having the second instance of dune send RPC build command to the RPC server, and the RPC server then sends diagnostic messages back to the first instance of dune.Currently this is only implemented for the
dune buildcommand, and promoting changes into source files is not supported. There are also some subtle differences between the output ofdune buildis performing the build itself and when it's acting as an RPC client, such as file paths being absolute rather than relative and the underline under code errors losing its color.