Skip to content

Commit 1d6ce4f

Browse files
committed
fix: don't wait for build lock
Signed-off-by: Ali Caglayan <alizter@gmail.com>
1 parent 7437932 commit 1d6ce4f

File tree

8 files changed

+134
-7
lines changed

8 files changed

+134
-7
lines changed

bin/build.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ let build =
227227
let open Fiber.O in
228228
Rpc.Rpc_common.fire_request
229229
~name:"build"
230-
~wait:true
230+
~wait:false
231231
~lock_held_by
232232
builder
233233
Dune_rpc_impl.Decl.build

bin/exec.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ let build_prog_via_rpc_if_necessary ~dir ~no_rebuild builder lock_held_by prog =
229229
let open Fiber.O in
230230
Rpc.Rpc_common.fire_request
231231
~name:"build"
232-
~wait:true
232+
~wait:false
233233
~lock_held_by
234234
builder
235235
Dune_rpc_impl.Decl.build

bin/fmt.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ let run_fmt_command ~common ~config ~preview builder =
4848
Scheduler.no_build_no_rpc ~config (fun () ->
4949
Rpc.Rpc_common.fire_request
5050
~name:"format"
51-
~wait:true
51+
~wait:false
5252
~warn_forwarding:false
5353
~lock_held_by
5454
builder

bin/promotion.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ module Apply = struct
8888
let open Fiber.O in
8989
Rpc.Rpc_common.fire_request
9090
~name:"promote_many"
91-
~wait:true
91+
~wait:false
9292
~lock_held_by
9393
builder
9494
Dune_rpc_private.Procedures.Public.promote_many

bin/rpc/rpc_common.ml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,18 @@ let send_request ~f connection name =
122122
~f
123123
;;
124124

125+
let raise_rpc_not_found ~lock_held_by =
126+
User_error.raise
127+
(match lock_held_by with
128+
| Dune_util.Global_lock.Lock_held_by.Unknown -> [ Pp.text "RPC server not running." ]
129+
| Pid_from_lockfile pid ->
130+
[ Pp.textf
131+
"Another dune instance (pid: %d) has the build directory locked but is not \
132+
running an RPC server."
133+
pid
134+
])
135+
;;
136+
125137
let fire_request
126138
~name
127139
~wait
@@ -132,7 +144,15 @@ let fire_request
132144
arg
133145
=
134146
let open Fiber.O in
135-
let* connection = establish_client_session ~wait in
147+
let* connection =
148+
Fiber.map_reduce_errors
149+
(module Monoid.Unit)
150+
~on_error:(fun _ -> Fiber.return ())
151+
(fun () -> establish_client_session ~wait)
152+
>>| function
153+
| Ok conn -> conn
154+
| Error () -> raise_rpc_not_found ~lock_held_by
155+
in
136156
if should_warn ~warn_forwarding builder then warn_ignore_arguments lock_held_by;
137157
send_request connection name ~f:(fun client -> request_exn client request arg)
138158
;;
@@ -147,7 +167,15 @@ let fire_notification
147167
arg
148168
=
149169
let open Fiber.O in
150-
let* connection = establish_client_session ~wait in
170+
let* connection =
171+
Fiber.map_reduce_errors
172+
(module Monoid.Unit)
173+
~on_error:(fun _ -> Fiber.return ())
174+
(fun () -> establish_client_session ~wait)
175+
>>| function
176+
| Ok conn -> conn
177+
| Error () -> raise_rpc_not_found ~lock_held_by
178+
in
151179
if should_warn ~warn_forwarding builder then warn_ignore_arguments lock_held_by;
152180
send_request connection name ~f:(fun client -> notify_exn client notification arg)
153181
;;

bin/tools/tools_common.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let build_dev_tool_via_rpc builder lock_held_by dev_tool =
3939
let open Fiber.O in
4040
Rpc.Rpc_common.fire_request
4141
~name:"build"
42-
~wait:true
42+
~wait:false
4343
~lock_held_by
4444
builder
4545
Dune_rpc_impl.Decl.build
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
Test that dune fails fast when the build lock is held but no RPC server is
2+
available. This is a regression test for
3+
https://github.com/ocaml/dune/issues/12900
4+
5+
$ cat > dune-project <<EOF
6+
> (lang dune 3.18)
7+
> EOF
8+
9+
$ cat > dune <<EOF
10+
> (executable (name foo))
11+
> EOF
12+
13+
$ cat > foo.ml <<EOF
14+
> let () = print_endline "hello"
15+
> EOF
16+
17+
Helper to run a command while holding the build lock without an RPC server:
18+
19+
$ with_build_lock_held() {
20+
> mkdir -p _build
21+
> (
22+
> flock -x 9
23+
> printf '%s' $$ > _build/.lock
24+
> "$@" 2>&1 | sed 's/pid: [0-9]*/pid: PID/'
25+
> ) 9>_build/.lock
26+
> }
27+
28+
Hold the lock without running an RPC server, then try various commands.
29+
They should all fail immediately instead of hanging.
30+
31+
$ with_build_lock_held dune build
32+
Error: Another dune instance (pid: PID) has the build directory locked
33+
but is not running an RPC server.
34+
35+
$ with_build_lock_held dune exec ./foo.exe
36+
Error: Another dune instance (pid: PID) has the build directory locked
37+
but is not running an RPC server.
38+
39+
$ with_build_lock_held dune fmt
40+
Error: Another dune instance (pid: PID) has the build directory locked
41+
but is not running an RPC server.
42+
43+
$ with_build_lock_held dune promote
44+
Error: Another dune instance (pid: PID) has the build directory locked
45+
but is not running an RPC server.
46+
47+
$ with_build_lock_held dune runtest
48+
Error: Another dune instance (pid: PID) has the build directory locked
49+
but is not running an RPC server.
50+
51+
We are not starting an RPC server for clean, but we do care if the lock is
52+
held.
53+
54+
$ with_build_lock_held dune clean
55+
Error: A running dune (pid: PID) instance has locked the build directory.
56+
If this is not the case, please delete "_build/.lock".
57+
58+
Explicit RPC commands do not check the lock first, so they get a simpler error:
59+
60+
$ dune rpc ping
61+
Error: RPC server not running.
62+
[1]
63+
64+
$ dune rpc build
65+
Error: RPC server not running.
66+
[1]
67+
68+
$ dune shutdown
69+
Error: RPC server not running.
70+
[1]
71+
72+
$ dune diagnostics
73+
Error: RPC server not running.
74+
[1]
75+
76+
Commands that start their own RPC server will fail when trying to acquire the
77+
lock:
78+
79+
$ with_build_lock_held dune utop . 2>&1 | head -3
80+
Error: A running dune (pid: PID) instance has locked the build directory.
81+
If this is not the case, please delete "_build/.lock".
82+
83+
$ with_build_lock_held dune ocaml top 2>&1 | head -3
84+
Error: A running dune (pid: PID) instance has locked the build directory.
85+
If this is not the case, please delete "_build/.lock".
86+
87+
$ with_build_lock_held dune printenv 2>&1 | head -3
88+
Error: A running dune (pid: PID) instance has locked the build directory.
89+
If this is not the case, please delete "_build/.lock".
90+
91+
$ with_build_lock_held dune describe workspace 2>&1 | head -3
92+
Error: A running dune (pid: PID) instance has locked the build directory.
93+
If this is not the case, please delete "_build/.lock".
94+

test/blackbox-tests/test-cases/dune

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,8 @@
133133
(cram
134134
(applies_to trace-file)
135135
(deps %{bin:perl}))
136+
137+
(cram
138+
(applies_to build-lock-no-rpc)
139+
(deps %{bin:flock})
140+
(timeout 5))

0 commit comments

Comments
 (0)