Skip to content

Commit 8743f31

Browse files
authored
Allow rpc-triggered builds in eager watch mode (#11622)
When dune is started in eager watch mode (e.g. by running `dune build --watch`) it starts an RPC server, but prior to this change it would reject RPC requests to build targets. This is a step towards being able to run dune commands that trigger build (e.g. `build`, `exec`, `test`) while watch mode is running. Signed-off-by: Stephen Sherratt <[email protected]>
1 parent d0a46ac commit 8743f31

File tree

7 files changed

+47
-54
lines changed

7 files changed

+47
-54
lines changed

bin/build_cmd.ml

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,28 +83,38 @@ let run_build_system ~common ~request =
8383
Fiber.return ())
8484
;;
8585

86-
let run_build_command_poll_eager ~(common : Common.t) ~config ~request : unit =
87-
Scheduler.go_with_rpc_server_and_console_status_reporting ~common ~config (fun () ->
88-
Scheduler.Run.poll (run_build_system ~common ~request))
89-
;;
90-
91-
let run_build_command_poll_passive ~(common : Common.t) ~config ~request:_ : unit =
92-
(* CR-someday aalekseyev: It would've been better to complain if [request] is
93-
non-empty, but we can't check that here because [request] is a function.*)
86+
let poll_handling_rpc_build_requests ~(common : Common.t) ~config =
9487
let open Fiber.O in
9588
let rpc =
9689
match Common.rpc common with
9790
| `Allow server -> server
9891
| `Forbid_builds -> Code_error.raise "rpc server must be allowed in passive mode" []
9992
in
93+
Scheduler.Run.poll_passive
94+
~get_build_request:
95+
(let+ (Build (targets, ivar)) = Dune_rpc_impl.Server.pending_build_action rpc in
96+
let request setup =
97+
Target.interpret_targets (Common.root common) config setup targets
98+
in
99+
run_build_system ~common ~request, ivar)
100+
;;
101+
102+
let run_build_command_poll_eager ~(common : Common.t) ~config ~request : unit =
103+
Scheduler.go_with_rpc_server_and_console_status_reporting ~common ~config (fun () ->
104+
let open Fiber.O in
105+
(* Run two fibers concurrently. One is responible for rebuilding targets
106+
named on the command line in reaction to file system changes. The other
107+
is responsible for building targets named in RPC build requests. *)
108+
let+ () = Scheduler.Run.poll (run_build_system ~common ~request)
109+
and+ () = poll_handling_rpc_build_requests ~common ~config in
110+
())
111+
;;
112+
113+
let run_build_command_poll_passive ~common ~config ~request:_ : unit =
114+
(* CR-someday aalekseyev: It would've been better to complain if [request] is
115+
non-empty, but we can't check that here because [request] is a function.*)
100116
Scheduler.go_with_rpc_server_and_console_status_reporting ~common ~config (fun () ->
101-
Scheduler.Run.poll_passive
102-
~get_build_request:
103-
(let+ (Build (targets, ivar)) = Dune_rpc_impl.Server.pending_build_action rpc in
104-
let request setup =
105-
Target.interpret_targets (Common.root common) config setup targets
106-
in
107-
run_build_system ~common ~request, ivar))
117+
poll_handling_rpc_build_requests ~common ~config)
108118
;;
109119

110120
let run_build_command_once ~(common : Common.t) ~config ~request =

bin/common.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,6 @@ let build (builder : Builder.t) =
11551155
~registry
11561156
~root:root.dir
11571157
~handle:Dune_rules_rpc.register
1158-
~watch_mode_config:builder.watch
11591158
~parse_build:Dune_rules_rpc.parse_build
11601159
stats))
11611160
else `Forbid_builds

doc/changes/11622.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Allow build RPC messages to be handled by dune's RPC server in eager watch
2+
mode (#11622, @gridbugs)

doc/rpc.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,17 @@ uses the ``dune-rpc`` and ``dune-rpc-lwt`` packages.
5656
Connecting
5757
==========
5858

59-
To connect to Dune's RPC server, it needs to be started in watch mode. It is
60-
possible to use ``dune build --passive-watch-mode`` to start an RPC server which
61-
will listen for requests without starting a build by itself. Then ``dune rpc
62-
build .`` will connect to it, trigger a build, and report status.
59+
To connect to Dune's RPC server, it needs to be started in watch mode. There
60+
are two ways of doing this:
61+
62+
- Run ``dune build --passive-watch-mode`` to start an RPC server which will
63+
listen for requests without starting a build by itself...
64+
- Or run ``dune build --watch`` to start a build server that rebuilds the
65+
project's default target when source files change and *also* starts an RPC
66+
server that listens for requests.
67+
68+
Then ``dune rpc build .`` will connect to it, trigger a build, and report
69+
status.
6370

6471
.. _lwt: https://github.com/ocsigen/lwt
6572
.. _Dune_rpc: https://github.com/ocaml/dune/blob/main/otherlibs/dune-rpc/dune_rpc.mli

src/dune_rpc_impl/server.ml

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ type 'a t =
192192
{ config : Run.t
193193
; pending_build_jobs : ('a list * Build_outcome.t Fiber.Ivar.t) Job_queue.t
194194
; parse_build : string -> 'a
195-
; watch_mode_config : Watch_mode_config.t
196195
; mutable clients : Clients.t
197196
}
198197

@@ -321,23 +320,10 @@ let handler (t : _ t Fdecl.t) handle : 'a Dune_rpc_server.Handler.t =
321320
let () =
322321
let build _session targets =
323322
let server = Fdecl.get t in
324-
match server.watch_mode_config with
325-
| No -> assert false
326-
| Yes Eager ->
327-
let error =
328-
Dune_rpc.Response.Error.create
329-
~kind:Invalid_request
330-
~message:
331-
"the rpc server is running with eager watch mode using --watch. to run \
332-
builds through an rpc client, start the server using --passive-watch-mode"
333-
()
334-
in
335-
raise (Dune_rpc.Response.Error.E error)
336-
| Yes Passive ->
337-
let ivar = Fiber.Ivar.create () in
338-
let targets = List.map targets ~f:server.parse_build in
339-
let* () = Job_queue.write server.pending_build_jobs (targets, ivar) in
340-
Fiber.Ivar.read ivar
323+
let ivar = Fiber.Ivar.create () in
324+
let targets = List.map targets ~f:server.parse_build in
325+
let* () = Job_queue.write server.pending_build_jobs (targets, ivar) in
326+
Fiber.Ivar.read ivar
341327
in
342328
Handler.implement_request rpc Decl.build build
343329
in
@@ -405,7 +391,7 @@ let handler (t : _ t Fdecl.t) handle : 'a Dune_rpc_server.Handler.t =
405391
rpc
406392
;;
407393

408-
let create ~lock_timeout ~registry ~root ~watch_mode_config ~handle stats ~parse_build =
394+
let create ~lock_timeout ~registry ~root ~handle stats ~parse_build =
409395
let t = Fdecl.create Dyn.opaque in
410396
let pending_build_jobs = Job_queue.create () in
411397
let handler = Dune_rpc_server.make (handler t handle) in
@@ -443,14 +429,7 @@ let create ~lock_timeout ~registry ~root ~watch_mode_config ~handle stats ~parse
443429
; server_ivar = Fiber.Ivar.create ()
444430
}
445431
in
446-
let res =
447-
{ config
448-
; pending_build_jobs
449-
; watch_mode_config
450-
; clients = Clients.empty
451-
; parse_build
452-
}
453-
in
432+
let res = { config; pending_build_jobs; clients = Clients.empty; parse_build } in
454433
Fdecl.set t res;
455434
res
456435
;;

src/dune_rpc_impl/server.mli

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ val create
44
: lock_timeout:float option
55
-> registry:[ `Add | `Skip ]
66
-> root:string
7-
-> watch_mode_config:Watch_mode_config.t
87
-> handle:(unit Dune_rpc_server.Handler.t -> unit)
98
(** register additional requests or notifications *)
109
-> Dune_stats.t option
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Show error when trying to build through rpc when server is running eager watch
1+
Demonstrate building through rpc when server is running in eager watch
22

33
$ echo '(lang dune 3.8)' > dune-project
44
$ mkdir src
@@ -9,13 +9,10 @@ Show error when trying to build through rpc when server is running eager watch
99
$ dune build @all
1010
$ dune build --watch &
1111
Success, waiting for filesystem changes...
12+
Success, waiting for filesystem changes...
1213

1314
$ dune rpc build --wait .
14-
Error: { payload = None
15-
; message =
16-
"the rpc server is running with eager watch mode using --watch. to run builds through an rpc client, start the server using --passive-watch-mode"
17-
; kind = Invalid_request
18-
}
15+
Success
1916

2017
$ dune shutdown
2118
$ wait

0 commit comments

Comments
 (0)