1212LOGGER = logging .getLogger (__name__ )
1313
1414
15- def get_netstat_out () -> str :
16- """Get output of the `netstat` command."""
15+ def get_netstat_listen () -> str :
16+ """Get listing of listening services from the `netstat` command."""
1717 try :
1818 return helpers .run_command (
1919 "netstat -pant | grep -E 'LISTEN|TIME_WAIT'" , ignore_fail = True , shell = True
@@ -23,11 +23,23 @@ def get_netstat_out() -> str:
2323 return ""
2424
2525
26+ def get_netstat_conn () -> str :
27+ """Get listing of connections from the `netstat` command."""
28+ try :
29+ return helpers .run_command ("netstat -pant" , ignore_fail = True ).decode ()
30+ except Exception as excp :
31+ LOGGER .error (f"Failed to fetch netstat output: { excp } " ) # noqa: TRY400
32+ return ""
33+
34+
2635def kill_old_cluster (instance_num : int , log_func : tp .Callable [[str ], None ]) -> None : # noqa: C901
2736 """Attempt to kill all processes left over from a previous cluster instance."""
2837
29- def _get_netstat_split () -> list [str ]:
30- return get_netstat_out ().replace ("\t " , " " ).splitlines ()
38+ def _get_listen_split () -> list [str ]:
39+ return get_netstat_listen ().replace ("\t " , " " ).splitlines ()
40+
41+ def _get_conn_split () -> list [str ]:
42+ return get_netstat_conn ().replace ("\t " , " " ).splitlines ()
3143
3244 def _get_pid (line : str ) -> int | None :
3345 try :
@@ -64,11 +76,12 @@ def _get_proc_cmdline(pid: int) -> str:
6476 * port_nums .node_ports ,
6577 )
6678 ]
79+ ports_re = re .compile (r"|" .join (re .escape (p ) for p in port_strs ))
6780
6881 # Attempt to kill the `supervisord` process first. If successful, this will also kill all the
6982 # processes started by supervisor.
7083 port_supervisor_str = port_strs [0 ]
71- for line in _get_netstat_split ():
84+ for line in _get_listen_split ():
7285 if port_supervisor_str not in line :
7386 continue
7487 pid = _get_pid (line )
@@ -79,10 +92,9 @@ def _get_proc_cmdline(pid: int) -> str:
7992 break
8093
8194 # Kill all the leftover processes, if possible, and wait for them to finish
82- ports_re = re .compile (r"|" .join (re .escape (p ) for p in port_strs ))
8395 for _ in range (5 ):
8496 found = False
85- for line in _get_netstat_split ():
97+ for line in _get_listen_split ():
8698 if not ports_re .search (line ):
8799 continue
88100 found = True
@@ -95,3 +107,15 @@ def _get_proc_cmdline(pid: int) -> str:
95107 break
96108 if not found :
97109 break
110+
111+ # Wait until all connections are closed
112+ for _ in range (3 ):
113+ found = False
114+ for line in _get_conn_split ():
115+ if not ports_re .search (line ):
116+ continue
117+ found = True
118+ time .sleep (5 )
119+ break
120+ if not found :
121+ break
0 commit comments