Skip to content

add purge queue observability via cache_purge_status and active_slots - #67

Open
hsntgm wants to merge 1 commit into
nginx-modules:masterfrom
psaux-it:status-endpoint
Open

add purge queue observability via cache_purge_status and active_slots#67
hsntgm wants to merge 1 commit into
nginx-modules:masterfrom
psaux-it:status-endpoint

Conversation

@hsntgm

@hsntgm hsntgm commented Jun 18, 2026

Copy link
Copy Markdown

The main aim is observability of the background purge queue.

Before this PR, the background purge queue was completely opaque. Once a purge request was enqueued and the 202 was returned to the client, there was no way to know:

  • whether the purge had actually been processed yet
  • whether the worker was currently walking the cache directory
  • whether the queue was backing up or full

The PR solves this in two parts that work together:

  • The tracking mechanism (active_slots) records which cache paths are currently being walked by a background worker. Without this, you could count queued items but you couldn't tell if one was actively being processed right now (it's already been dequeued but the filesystem walk hasn't finished).

  • The status endpoint exposes that internal state as a queryable JSON API, giving operators a way to poll and answer the question: "Has my async purge_all actually happened yet?"

Indroduce new cache_purge_status directive that serves per‑zone statistics,

# Background queue status
location = /bg_purge_status {
    allow 127.0.0.1;
    allow 172.16.0.0/12;
    deny all;

    cache_purge_status /var/cache/nginx;
}

so operators can monitor each cache directory independently.

The endpoint responds with the following JSON

queue_size
purge_all_pending
queue_full
purge_in_flight

all read under the same queue mutex to guarantee a consistent snapshot.

A downstream process can reliably determine that async purge_all or Partial/wildcard (key) has completed by polling the endpoint and checking;

queue_size == 0 AND purge_in_flight == false (for that cache_path)

This signals indicates bg purge completed, the directory walk has finished, and no walk is still in progress.

This is practically important in deployment scenarios where something downstream (a CDN origin check, a deployment pipeline, a health check, preload action) needs to wait for a cache zone to actually be cleared before proceeding.


Test

# Enable background queue for async purge and the status endpoint
cache_purge_background_queue on;
cache_purge_throttle_ms  100ms;
cache_purge_batch_size   10;
#!/usr/bin/env bash
set -euo pipefail

STATUS_URL="https://nginx/cache_purge_status"
PURGE_URL="https://nginx/purge_all"
HOST_HEADER="Host: localhost"

# Trigger async purge_all
curl -k -X GET -H "$HOST_HEADER" "$PURGE_URL"
echo "Purge triggered, waiting for background walk to finish..."

# Poll until safe for downstream process to start
while true; do
    response=$(curl -sk -H "$HOST_HEADER" "$STATUS_URL")
    if command -v jq &> /dev/null; then
        queue_size=$(echo "$response" | jq -r '.queue_size')
        purge_in_flight=$(echo "$response" | jq -r '.purge_in_flight')
    else
        exit 1
    fi

    echo "$(date +%T.%3N) queue_size=$queue_size purge_in_flight=$purge_in_flight"

    if [[ "$queue_size" == "0" && "$purge_in_flight" == "false" ]]; then
        echo "Async Purge All completed, safe to Preload."
        break
    fi

    sleep 0.001
done
12:22:36.224 queue_size=1 purge_in_flight=false
12:22:36.256 queue_size=1 purge_in_flight=false
12:22:36.287 queue_size=1 purge_in_flight=false
12:22:36.317 queue_size=1 purge_in_flight=false
12:22:36.347 queue_size=1 purge_in_flight=false
12:22:36.379 queue_size=1 purge_in_flight=false
12:22:36.409 queue_size=1 purge_in_flight=false
12:22:36.440 queue_size=1 purge_in_flight=false
12:22:36.471 queue_size=1 purge_in_flight=false
12:22:36.502 queue_size=1 purge_in_flight=false
12:22:36.533 queue_size=1 purge_in_flight=false
12:22:36.563 queue_size=1 purge_in_flight=false
12:22:36.593 queue_size=1 purge_in_flight=false
12:22:36.623 queue_size=1 purge_in_flight=false
12:22:36.653 queue_size=1 purge_in_flight=false
12:22:36.683 queue_size=1 purge_in_flight=false
12:22:36.713 queue_size=1 purge_in_flight=false
12:22:36.746 queue_size=0 purge_in_flight=true
12:22:36.777 queue_size=0 purge_in_flight=true
12:22:36.808 queue_size=0 purge_in_flight=true
12:22:36.839 queue_size=0 purge_in_flight=false ******
Async Purge All completed, safe to Preload.

Best~Hasan

The main aim is observability of the background purge queue.

Before this patch, the background purge queue was completely opaque. Once a purge request was enqueued and the 202 was returned to the client, there was no way to know:

* whether the purge had actually been processed yet
* whether the worker was currently walking the cache directory
* whether the queue was backing up or full

The patch solves this in two parts that work together:

* The tracking mechanism (active_slots) records which cache paths are currently being walked by a background worker. Without this, you could count queued items but you couldn't tell if one was actively being processed right now (it's already been dequeued but the filesystem walk hasn't finished).

* The status endpoint (cache_purge_status) exposes that internal state as a queryable JSON API, giving operators a way to poll and answer the question: "Has my purge_all actually happened yet?"

The new cache_purge_status directive (e.g. cache_purge_status /data/nginx/cache) serves per‑zone statistics, so operators can monitor each cache directory independently.

The endpoint responds with JSON fields queue_size, purge_all_pending, queue_full, and purge_in_flight, all read under the same queue mutex to guarantee a consistent snapshot.

A downstream process can reliably determine that purge_all or Partial/wildcard (key*) has completed by polling the endpoint and checking;

queue_size == 0 AND purge_in_flight == false (for that cache_path)

This signals indicates bg purge completed, the directory walk has finished, and no walk is still in progress.

This is practically important in deployment scenarios where something downstream (a CDN origin check, a deployment pipeline, a health check, preload action) needs to wait for a cache zone to actually be cleared before proceeding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant