Skip to content

Commit c7a841b

Browse files
jonatankloskojosevalim
authored andcommitted
Add an environment variable to optionally disable compilation locking (#14129)
1 parent f3dfb72 commit c7a841b

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

lib/mix/lib/mix.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ defmodule Mix do
352352
* `MIX_INSTALL_DIR` *(since v1.12.0)* - specifies directory where `Mix.install/2` keeps
353353
install cache
354354
355+
* `MIX_OS_CONCURRENCY_LOCK` - when set to `0` or `false`, disables mix compilation locking.
356+
While not recommended, this may be necessary in cases where hard links or TCP sockets are
357+
not available. When opting for this behaviour, make sure to not start concurrent compilations
358+
of the same project.
359+
355360
* `MIX_PATH` - appends extra code paths
356361
357362
* `MIX_PROFILE` - a list of comma-separated Mix tasks to profile the time spent on

lib/mix/lib/mix/sync/lock.ex

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ defmodule Mix.Sync.Lock do
7979
This function can also be called if this process already has the
8080
lock. In such case the function is executed immediately.
8181
82+
When the `MIX_OS_CONCURRENCY_LOCK` environment variable is set to
83+
a falsy value, the lock is ignored and the function is executed
84+
immediately.
85+
8286
## Options
8387
8488
* `:on_taken` - a one-arity function called if the lock is held
@@ -96,9 +100,9 @@ defmodule Mix.Sync.Lock do
96100
path = Path.join([System.tmp_dir!(), "mix_lock", hash])
97101

98102
pdict_key = {__MODULE__, path}
99-
has_lock? = Process.get(pdict_key)
103+
has_lock? = Process.get(pdict_key, false)
100104

101-
if has_lock? do
105+
if has_lock? or lock_disabled?() do
102106
fun.()
103107
else
104108
lock = lock(path, opts[:on_taken])
@@ -115,6 +119,8 @@ defmodule Mix.Sync.Lock do
115119
end
116120
end
117121

122+
defp lock_disabled?(), do: System.get_env("MIX_OS_CONCURRENCY_LOCK") in ~w(0 false)
123+
118124
defp lock(path, on_taken) do
119125
File.mkdir_p!(path)
120126

@@ -198,11 +204,12 @@ defmodule Mix.Sync.Lock do
198204
:invalidated
199205

200206
{:error, reason} ->
201-
raise File.LinkError,
202-
reason: reason,
203-
action: "create hard link",
204-
existing: port_path,
205-
new: lock_path
207+
Mix.raise("""
208+
could not create hard link from #{port_path} to "#{lock_path}: #{:file.format_error(reason)}.
209+
210+
Hard link support is required for Mix compilation locking. If your system \
211+
does not support hard links, set MIX_OS_CONCURRENCY_LOCK=0\
212+
""")
206213
end
207214
end
208215

0 commit comments

Comments
 (0)