@@ -67,6 +67,7 @@ defmodule Mix.Tasks.Deps.Partition do
6767 ]
6868
6969 options = [
70+ :exit_status ,
7071 :binary ,
7172 :hide ,
7273 :use_stdio ,
@@ -164,12 +165,10 @@ defmodule Mix.Tasks.Deps.Partition do
164165 send_deps_and_server_loop ( [ client | available ] , busy , deps , status )
165166
166167 { :tcp_closed , socket } ->
167- shutdown_clients ( available ++ busy )
168- Mix . raise ( "mix deps.partition #{ inspect ( socket ) } closed unexpectedly" )
168+ tcp_failed! ( "closed unexpectedly" , socket , available , busy )
169169
170170 { :tcp_error , socket , error } ->
171- shutdown_clients ( available ++ busy )
172- Mix . raise ( "mix deps.partition #{ inspect ( socket ) } errored: #{ inspect ( error ) } " )
171+ tcp_failed! ( "errored: #{ inspect ( error ) } " , socket , available , busy )
173172
174173 { port , { :data , { eol , data } } } ->
175174 with % { index: index } <-
@@ -189,6 +188,26 @@ defmodule Mix.Tasks.Deps.Partition do
189188 end
190189 end
191190
191+ defp tcp_failed! ( message , socket , available , busy ) do
192+ { % { port: port } = client , busy } = pop_with ( busy , & ( & 1 . socket == socket ) )
193+
194+ # Let's make sure it has all been written out
195+ # but don't wait for more than 5 seconds if it
196+ # gets stuck for some unknown reason
197+ receive do
198+ { ^ port , { :exit_status , _ } } -> :ok
199+ after
200+ 5_000 -> Mix . shell ( ) . error ( "Timed out waiting for port exit #{ inspect ( port ) } " )
201+ end
202+
203+ shutdown_clients ( available ++ busy ++ [ client ] )
204+
205+ Mix . raise (
206+ "mix deps.partition #{ inspect ( socket ) } #{ message } " <>
207+ "(set MIX_OS_DEPS_COMPILE_PARTITION_COUNT=1 to run in serial)"
208+ )
209+ end
210+
192211 defp shutdown_clients ( clients ) do
193212 Enum . each ( clients , fn % { socket: socket , port: port , index: index } ->
194213 if Mix . debug? ( ) do
@@ -201,18 +220,22 @@ defmodule Mix.Tasks.Deps.Partition do
201220 end
202221
203222 defp close_port ( port , prefix ) do
223+ try do
224+ Port . close ( port )
225+ catch
226+ _ , _ -> :ok
227+ end
228+
229+ loop_close_port ( port , prefix )
230+ end
231+
232+ defp loop_close_port ( port , prefix ) do
204233 receive do
205- { ^ port , { :data , { :eol , data } } } -> [ prefix , data , ?\n | close_port ( port , prefix ) ]
206- { ^ port , { :data , { :noeol , data } } } -> [ data | close_port ( port , prefix ) ]
234+ { ^ port , { :data , { :eol , data } } } -> [ prefix , data , ?\n | loop_close_port ( port , prefix ) ]
235+ { ^ port , { :data , { :noeol , data } } } -> [ data | loop_close_port ( port , prefix ) ]
236+ { ^ port , { :exit_status , _ } } -> loop_close_port ( port , prefix )
207237 after
208- 0 ->
209- try do
210- Port . close ( port )
211- catch
212- _ , _ -> :ok
213- end
214-
215- [ ]
238+ 0 -> [ ]
216239 end
217240 end
218241
0 commit comments