#!/bin/bash
# Admits the queued collectors one at a time, only while the app container has room.
#
# Collectors share the app container's 1 GB cgroup with uvicorn. Eight of them sit at ~73-80 MiB
# each (measured, 18 Sep), which is ~73% of the cap; the last three would take it to ~96% and
# memory grows as a run accumulates. So the queue waits for real headroom rather than assuming it.
set -u
D="$(cd "$(dirname "$0")" && pwd)"
CEILING_MIB=620          # admit only below this; one more collector must still fit under the cap
LOG="$D/admit-queue.log"

mem_mib() {
  docker stats --no-stream --format '{{.MemUsage}}' dutyfreeprofessor-app 2>/dev/null \
    | awk '{sub(/MiB.*/,"",$1); sub(/GiB.*/,"",$1); print int($1)}'
}
running_for() {  # a source already collecting? never start a second run of one
  docker exec dutyfreeprofessor-db psql -U dfp -d dfp -tAc \
    "SELECT count(*) FROM collection_runs r JOIN sources s ON s.id=r.source_id
     WHERE r.status='running' AND s.slug='$1';" 2>/dev/null | tr -d '[:space:]'
}

echo "$(date '+%F %T') queue starts: $*" >> "$LOG"
for s in "$@"; do
  while :; do
    m=$(mem_mib)
    [ -z "$m" ] && m=9999
    if [ "$m" -lt "$CEILING_MIB" ] && [ "$(running_for "$s")" = "0" ]; then
      echo "$(date '+%F %T') admitting $s (app at ${m}MiB)" >> "$LOG"
      setsid nohup docker exec dutyfreeprofessor-app python -m app.cli collect --source "$s" \
        > "$D/$s.log" 2>&1 < /dev/null &
      sleep 90   # let it settle before judging headroom again
      break
    fi
    sleep 120
  done
done
echo "$(date '+%F %T') queue done" >> "$LOG"
