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 ...@@ -265,9 +265,13 @@ DIGGER
} }
# Allocate a free table number in range 200-250 (step 10) # 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() alloc_table()
{ {
local name="$1" local name="$1"
(
flock 8
local used=$(awk '/^[0-9]/ {print $1}' /etc/iproute2/rt_tables | sort -n) local used=$(awk '/^[0-9]/ {print $1}' /etc/iproute2/rt_tables | sort -n)
local num=200 local num=200
while [ $num -le 250 ] ; do while [ $num -le 250 ] ; do
...@@ -281,6 +285,7 @@ alloc_table() ...@@ -281,6 +285,7 @@ alloc_table()
done done
log "ERROR: Cannot allocate table for $name: range 200-250 exhausted" >&2 log "ERROR: Cannot allocate table for $name: range 200-250 exhausted" >&2
return 1 return 1
) 8>"$RT_TABLES_LOCK"
} }
# Look up table number by name; allocate if not found # Look up table number by name; allocate if not found
...@@ -767,27 +772,24 @@ for line in sys.stdin: ...@@ -767,27 +772,24 @@ for line in sys.stdin:
return 0 return 0
} }
# --- Process a routes directory (works for both IPv4 and IPv6) --- # --- Process a single group (runs in subshell for parallel execution) ---
# Per-list tables: each .list file gets its own routing table # Args: gwdir resolve_func ipcmd label pref_base
process_routes() process_group()
{ {
local routes_dir="$1" _gwdir="$1"
_resolve_func="$2" _resolve_func="$2"
_ipcmd="$3" _ipcmd="$3"
_label="$4" # "(v6)" or "" _label="$4"
_pref_counter="$5"
[ -d "$routes_dir" ] || return 0
_pref_counter=$PREF_BASE
for _gwdir in "$routes_dir"/*/ ; do
[ -d "$_gwdir" ] || continue
local name=$(basename "$_gwdir") local name=$(basename "$_gwdir")
read_group_config "$_gwdir" "$_ipcmd" || continue read_group_config "$_gwdir" "$_ipcmd" || return 0
_gw="$gw" ; _has_metric="$has_metric" _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" ensure_state_dir "$group_state"
vlog "[$name]$_label gw=$_gw has_metric=${_has_metric:-0} dir=$_gwdir" vlog "[$name]$_label gw=$_gw has_metric=${_has_metric:-0} dir=$_gwdir"
...@@ -809,13 +811,10 @@ process_routes() ...@@ -809,13 +811,10 @@ process_routes()
done done
rm -rf "$STATE_DIR/$group_state"/*/ rm -rf "$STATE_DIR/$group_state"/*/
fi fi
continue return 0
fi fi
# --- Per-list loop --- # --- 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 for _f in $lists ; do
local bname=$(basename "$_f") local bname=$(basename "$_f")
local list_name="${bname%.list}" local list_name="${bname%.list}"
...@@ -847,7 +846,38 @@ process_routes() ...@@ -847,7 +846,38 @@ process_routes()
resolve_list_file resolve_list_file
load_list_routes && log "$_tag$_label Done" load_list_routes && log "$_tag$_label Done"
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 done
[ "$failed" -gt 0 ] && log "WARNING:$_label $failed group(s) failed" || true
} }
# --- Cleanup orphaned state dirs --- # --- 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