From a637ba532cb3be102e1678abc2937a46f1b5ba10 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge <5619885+DilumAluthge@users.noreply.github.com> Date: Sat, 24 Oct 2026 00:56:33 -0400 Subject: [PATCH 1/2] Worker: Bind to the first non-link-local IPv4 address This is a cherry-pick of https://github.com/JuliaLang/Distributed.jl/pull/137 (cherry picked from commit 3679026d7b510befdedfa8c6497e3cb032f9cea1) --- src/cluster.jl | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/cluster.jl b/src/cluster.jl index 0e85bbb..12563ac 100644 --- a/src/cluster.jl +++ b/src/cluster.jl @@ -1656,6 +1656,28 @@ function terminate_all_workers() end end +function choose_bind_addr() + # We prefer IPv4 over IPv6. + # + # We also prefer non-link-local over link-local. + # (This is because on HPC clusters, link-local addresses are usually not + # usable for communication between compute nodes. + # + # Therefore, our order of preference is: + # 1. Non-link-local IPv4 + # 2. Non-link-local IPv6 + # 3. Link-local IPv4 + # 4. Link-local IPv6 + addrs = getipaddrs() + i = something( + findfirst(ip -> !islinklocaladdr(ip) && ip isa IPv4, addrs), # first non-link-local IPv4 + findfirst(ip -> !islinklocaladdr(ip) && ip isa IPv6, addrs), # first non-link-local IPv6 + findfirst(ip -> ip isa IPv4, addrs), # first IPv4 + findfirst(ip -> ip isa IPv6, addrs), # first IPv6 + ) + return addrs[i] +end + # initialize the local proc network address / port function init_bind_addr() opts = JLOptions() @@ -1677,15 +1699,12 @@ function init_bind_addr() end end else - interfaces = _get_interfaces(IPv4) - if isempty(interfaces) - # Include IPv6 interfaces if there are no IPv4 ones - interfaces = _get_interfaces() - end - - if isempty(interfaces) - # All networking is unavailable, initialize bind_addr to the loopback address. - # An exception will be raised later if even that is unavailable. + bind_port = 0 + try + bind_addr = string(choose_bind_addr()) + catch + # All networking is unavailable, initialize bind_addr to the loopback address + # Will cause an exception to be raised only when used. bind_addr = "127.0.0.1" else # Pick the interface with the highest negotiated speed, if any From 482d74b00f82f4c994a2671d8ed4efb6667b950d Mon Sep 17 00:00:00 2001 From: Dilum Aluthge <5619885+DilumAluthge@users.noreply.github.com> Date: Sat, 24 Oct 2026 01:06:25 -0400 Subject: [PATCH 2/2] Re-do the conflict resolution, but this time stay more faithful to the way DistributedNext does things --- src/cluster.jl | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/cluster.jl b/src/cluster.jl index 12563ac..7cde178 100644 --- a/src/cluster.jl +++ b/src/cluster.jl @@ -1656,7 +1656,7 @@ function terminate_all_workers() end end -function choose_bind_addr() +function possible_bind_interfaces() # We prefer IPv4 over IPv6. # # We also prefer non-link-local over link-local. @@ -1668,14 +1668,24 @@ function choose_bind_addr() # 2. Non-link-local IPv6 # 3. Link-local IPv4 # 4. Link-local IPv6 - addrs = getipaddrs() - i = something( - findfirst(ip -> !islinklocaladdr(ip) && ip isa IPv4, addrs), # first non-link-local IPv4 - findfirst(ip -> !islinklocaladdr(ip) && ip isa IPv6, addrs), # first non-link-local IPv6 - findfirst(ip -> ip isa IPv4, addrs), # first IPv4 - findfirst(ip -> ip isa IPv6, addrs), # first IPv6 - ) - return addrs[i] + interfaces = _get_interfaces() + ipv4_nonlinklocal = filter(i -> !islinklocaladdr(i.ip) && i.ip isa IPv4, interfaces) # non-link-local IPv4 + ipv6_nonlinklocal = filter(i -> !islinklocaladdr(i.ip) && i.ip isa IPv6, interfaces) # non-link-local IPv6 + ipv4 = filter(i -> i.ip isa IPv4, interfaces) # IPv4 + ipv6 = filter(i -> i.ip isa IPv6, interfaces) # IPv6 + if !isempty(ipv4_nonlinklocal) + return ipv4_nonlinklocal + end + if !isempty(ipv6_nonlinklocal) + return ipv6_nonlinklocal + end + if !isempty(ipv4) + return ipv4 + end + if !isempty(ipv6) + return ipv6 + end + return Interface[] end # initialize the local proc network address / port @@ -1699,12 +1709,10 @@ function init_bind_addr() end end else - bind_port = 0 - try - bind_addr = string(choose_bind_addr()) - catch - # All networking is unavailable, initialize bind_addr to the loopback address - # Will cause an exception to be raised only when used. + interfaces = possible_bind_interfaces() + if isempty(interfaces) + # All networking is unavailable, initialize bind_addr to the loopback address. + # An exception will be raised later if even that is unavailable. bind_addr = "127.0.0.1" else # Pick the interface with the highest negotiated speed, if any