fix(concurrency): address gadfly review — fail-open pool + doc drift
Build & push image / build-and-push (pull_request) Successful in 4s
Build & push image / build-and-push (pull_request) Successful in 4s
Gadfly's own review of #27 surfaced a real robustness cluster (5 models, error-handling) plus stale comments I missed. Robustness — the flock permit pool could hang forever: - tryAcquire swallowed os.OpenFile errors and treated every flock error as "busy", so a broken/missing pool dir (or a filesystem without flock) would spin-poll indefinitely; the fanout context is uncancellable and the per-lens timeout only starts AFTER acquire returns. Can't trigger in the deploy (entrypoint mkdir -p's the dir) but fixed defensively. - tryAcquire now returns a structural error, distinguished from a healthy-full pool (EWOULDBLOCK = busy → keep polling). acquire FAILS OPEN on a structural error: logs once and runs the lens unthrottled rather than hanging the review. - acquire uses time.NewTimer + Stop() (no per-poll timer leak on cancellation). - activeLensSem warns on stderr when GADFLY_LENS_SEM_DIR is set but the size is invalid (was a silent degrade to unthrottled). - New test: a broken pool dir fails open promptly. Doc drift (stale references to the removed model cap): - main.go defaultLensConcurrency + runSpecialists doc, entrypoint.sh status pre-seed + lane-launch comments, and the pre-existing lens_concurrency_test.go header all updated to the provider-wide-budget wording. Accepted (graded real, not changed): all-models-start-at-once startup burst (intended tradeoff) and index-0 sweep bias (cosmetic). One false positive (one model using the whole budget is the intended lone-model behavior). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
+5
-5
@@ -354,8 +354,8 @@ BOARD_PID=""
|
||||
if [ "${GADFLY_STATUS_BOARD:-1}" != "0" ]; then
|
||||
rm -rf "$STATUS_DIR"; mkdir -p "$STATUS_DIR"
|
||||
# Pre-seed every model as queued so the board shows the full swarm from t=0,
|
||||
# even models still waiting on their provider lane's concurrency cap. Each
|
||||
# binary overwrites its own file with real per-lens detail once it starts.
|
||||
# even models whose lenses are still waiting on their provider's lens budget.
|
||||
# Each binary overwrites its own file with real per-lens detail once it starts.
|
||||
for m in "${MODEL_LIST[@]}"; do
|
||||
jq -n --arg model "$m" --arg provider "$(provider_of "$m")" \
|
||||
'{model:$model, provider:$provider, started:0, updated:0, done:false, lenses:[]}' \
|
||||
@@ -394,9 +394,9 @@ if [ "${GADFLY_PR_BUDGET_SECS:-0}" -gt 0 ] 2>/dev/null; then
|
||||
fi
|
||||
|
||||
log "providers: ${PROVIDERS:-none}"
|
||||
# Each provider lane runs in parallel; cap is enforced within each lane. Track
|
||||
# the lane PIDs so we wait ONLY for the review work — not the status board,
|
||||
# which intentionally runs until we signal it below.
|
||||
# Each provider lane runs in parallel; the shared lens budget throttles within
|
||||
# each lane. Track the lane PIDs so we wait ONLY for the review work — not the
|
||||
# status board, which intentionally runs until we signal it below.
|
||||
LANE_PIDS=()
|
||||
for p in $PROVIDERS; do
|
||||
run_lane "$p" &
|
||||
|
||||
Reference in New Issue
Block a user