cache.sh 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. # net-ops :: _lib/cache.sh
  2. # Lightweight state cache for --quick mode.
  3. # Stores the last probe's summary so we can decide whether to run the full
  4. # ladder or just the most failure-prone layers (rungs 5+6).
  5. CACHE_DIR="${NETOPS_CACHE_DIR:-${TMPDIR:-/tmp}/net-ops}"
  6. CACHE_FILE="$CACHE_DIR/last-state.json"
  7. CACHE_MAX_AGE_SECONDS="${NETOPS_CACHE_MAX_AGE:-600}" # 10 minutes default
  8. QUICK_MODE=0
  9. parse_quick_flag() {
  10. for a in "$@"; do
  11. [[ "$a" == "--quick" ]] && QUICK_MODE=1
  12. done
  13. }
  14. # Returns 0 if the last cached state is "all healthy and recent" — caller
  15. # should then skip rungs 1-4 and only run 5+6. Returns 1 otherwise.
  16. cache_indicates_healthy() {
  17. [[ "$QUICK_MODE" -eq 1 ]] || return 1
  18. [[ -f "$CACHE_FILE" ]] || return 1
  19. # File age check (BSD vs GNU stat compat)
  20. local mtime now age
  21. mtime=$(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE" 2>/dev/null)
  22. [[ -n "$mtime" ]] || return 1
  23. now=$(date +%s)
  24. age=$(( now - mtime ))
  25. (( age > CACHE_MAX_AGE_SECONDS )) && return 1
  26. # Parse: only return healthy if fail count was zero
  27. grep -q '"fail":0' "$CACHE_FILE" 2>/dev/null
  28. }
  29. # Save current state at end of probe.
  30. cache_save_state() {
  31. local pass="$1" fail="$2" first_fail="$3"
  32. mkdir -p "$CACHE_DIR" 2>/dev/null || return 0
  33. printf '{"ts":%d,"pass":%d,"fail":%d,"first_fail":%q}\n' \
  34. "$(date +%s)" "$pass" "$fail" "$first_fail" > "$CACHE_FILE" 2>/dev/null || true
  35. }
  36. # Predicate the probe can call to decide whether to run a given rung.
  37. # Args: rung_number (1..7). In quick mode, only 5 and 6 run.
  38. should_run_rung() {
  39. local rung="$1"
  40. if cache_indicates_healthy; then
  41. case "$rung" in
  42. 5|6) return 0 ;;
  43. *) return 1 ;;
  44. esac
  45. fi
  46. return 0
  47. }