Commit e61ab33a authored by Vitaly Lipatov's avatar Vitaly Lipatov

route-update: parallel group processing for faster DNS resolution

Process route groups in parallel using background subshells. Each group runs independently with its own pref base computed from the group's alphabetical index. Table allocation in /etc/iproute2/rt_tables is protected by flock to prevent races. On local-test with 3 groups: 163% CPU utilization confirms parallel execution. Co-Authored-By: 's avatarClaude Opus 4.6 (1M context) <noreply@anthropic.com>
parent 5de04da0
......@@ -265,9 +265,13 @@ DIGGER
}
# Allocate a free table number in range 200-250 (step 10)
# Uses flock to prevent race conditions during parallel group processing
RT_TABLES_LOCK="/var/lock/rt-tables.lock"
alloc_table()
{
local name="$1"
(
flock 8
local used=$(awk '/^[0-9]/ {print $1}' /etc/iproute2/rt_tables | sort -n)
local num=200
while [ $num -le 250 ] ; do
......@@ -281,6 +285,7 @@ alloc_table()
done
log "ERROR: Cannot allocate table for $name: range 200-250 exhausted" >&2
return 1
) 8>"$RT_TABLES_LOCK"
}
# Look up table number by name; allocate if not found
......@@ -767,27 +772,24 @@ for line in sys.stdin:
return 0
}
# --- Process a routes directory (works for both IPv4 and IPv6) ---
# Per-list tables: each .list file gets its own routing table
process_routes()
# --- Process a single group (runs in subshell for parallel execution) ---
# Args: gwdir resolve_func ipcmd label pref_base
process_group()
{
local routes_dir="$1"
_gwdir="$1"
_resolve_func="$2"
_ipcmd="$3"
_label="$4" # "(v6)" or ""
[ -d "$routes_dir" ] || return 0
_pref_counter=$PREF_BASE
_label="$4"
_pref_counter="$5"
for _gwdir in "$routes_dir"/*/ ; do
[ -d "$_gwdir" ] || continue
local name=$(basename "$_gwdir")
read_group_config "$_gwdir" "$_ipcmd" || continue
read_group_config "$_gwdir" "$_ipcmd" || return 0
_gw="$gw" ; _has_metric="$has_metric"
local group_state="$routes_dir/$name"
local group_state="$(dirname "$_gwdir")/$name"
# use routes_dir-relative path for state
group_state="${group_state#./}"
ensure_state_dir "$group_state"
vlog "[$name]$_label gw=$_gw has_metric=${_has_metric:-0} dir=$_gwdir"
......@@ -809,13 +811,10 @@ process_routes()
done
rm -rf "$STATE_DIR/$group_state"/*/
fi
continue
return 0
fi
# --- Per-list loop ---
# Align pref counter to next group boundary
_pref_counter=$(( (_pref_counter + PREF_GROUP_STEP - 1) / PREF_GROUP_STEP * PREF_GROUP_STEP ))
for _f in $lists ; do
local bname=$(basename "$_f")
local list_name="${bname%.list}"
......@@ -847,7 +846,38 @@ process_routes()
resolve_list_file
load_list_routes && log "$_tag$_label Done"
done
}
# --- Process a routes directory (works for both IPv4 and IPv6) ---
# Per-list tables: each .list file gets its own routing table
# Groups are processed in parallel for faster DNS resolution
process_routes()
{
local routes_dir="$1"
_resolve_func="$2"
_ipcmd="$3"
_label="$4" # "(v6)" or ""
[ -d "$routes_dir" ] || return 0
# Enumerate groups and assign pref bases
local group_index=0
local pids=""
for _gwdir in "$routes_dir"/*/ ; do
[ -d "$_gwdir" ] || continue
local pref_base=$((PREF_BASE + group_index * PREF_GROUP_STEP))
group_index=$((group_index + 1))
process_group "$_gwdir" "$_resolve_func" "$_ipcmd" "$_label" "$pref_base" &
pids="$pids $!"
done
# Wait for all groups to finish
local failed=0
for pid in $pids ; do
wait "$pid" || failed=$((failed + 1))
done
[ "$failed" -gt 0 ] && log "WARNING:$_label $failed group(s) failed" || true
}
# --- Cleanup orphaned state dirs ---
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment