fix(19.3-06): queue site-cache purges after commit and coalesce them (WR-01)
- PurgeSiteCacheAfterCommit queues the purge on a per-purger worker after commit: one request in flight, saves committed meanwhile collapse into one follow-up, so the admin request never waits for the site - new cooler.SiteCachePurger.Wait drains the queue; Handle.Close waits for it at shutdown (timeout plus one second) - Purge stays the synchronous send; exported names and signatures unchanged
This commit is contained in:
@@ -36,7 +36,7 @@ Use cases:
|
||||
- Keys carry a per-application prefix: `cache.prefix`, or by default `app.name` lower-cased with every run of other characters than `a-z` and `0-9` replaced by `_`, then `:` (`summer:` when `app.name` is empty). Cache keys are `<prefix>cache:<key>`, rate-limit keys `<prefix>rl:<key>`.
|
||||
- `cooler.OpenRedis` accepts `redis://`, `rediss://` (TLS) and `unix://` URLs, does not dial at construction, and skips the `CLIENT SETINFO` and maintenance-notification handshakes.
|
||||
- Only `serve` installs cooler: `route:list` and `surf.Assemble` in tests keep the in-process store and never dial Redis.
|
||||
- Site-cache purge: `cooler.SiteCachePurger` sends `POST {"kind":…,"slug":…}` with `Authorization: Bearer <token>` to `site_cache.purge_url`. `cooler.PurgeSiteCacheAfterCommit` registers that request on the save transaction through `lagoon.AfterCommit`, so it runs only after the save commits and never for a save that rolled back. One request per committed save, no debounce.
|
||||
- Site-cache purge: `cooler.SiteCachePurger` sends `POST {"kind":…,"slug":…}` with `Authorization: Bearer <token>` to `site_cache.purge_url`. `cooler.PurgeSiteCacheAfterCommit` queues that request on the save transaction through `lagoon.AfterCommit`, so it is queued only after the save commits and never for a save that rolled back. The save never waits for the site: a per-purger worker sends the request, with at most one in flight, and saves committed meanwhile collapse into one follow-up request (each purge clears the site's whole route cache), so a bulk delete sends at most two. `cooler.SiteCachePurger.Wait` drains the queue for tests and commands, and `cooler.Handle.Close` drains it at shutdown.
|
||||
- A purge never fails a save: each request is bounded by `cooler.SiteCachePurgeTimeout` (2 s) and detached from the request's cancellation, and a failure, an error status or a timeout is one warning (`cooler: site cache purge failed`) with the kind, slug and status. A success is one info line (`cooler: site cache purged`) with the purged count the site answered. Log lines and errors never carry the token or the full URL.
|
||||
- The purge URL must be http or https with a host and without user info or a fragment; plain http is accepted only for a loopback host (127.0.0.0/8, `::1`, `localhost`), so the token never crosses a network in clear. The token needs at least `cooler.SiteCachePurgeMinTokenLength` (32) characters, the same minimum the site's route applies. Setting only one of the two keys, or an invalid value, fails `serve` at boot with an error that names the key.
|
||||
- `cooler.Install` publishes the purger at boot unless a plugin already published one (a plugin that still reads its own deprecated keys), and `cooler.SiteCacheFromApp` gives admin hooks the same purger lazily in commands and tests that do not run `serve`. Plugins take the save transaction from `cabana.TxFromContext` themselves; cooler imports neither surf nor cabana.
|
||||
@@ -164,7 +164,7 @@ func AllowExport(ctx context.Context, app *backpack.App, fallback cooler.Attempt
|
||||
| `cooler.Install` | Reads cooler's config, publishes the Cache, opens and pings Redis when a Redis driver is selected, and returns a `cooler.Handle`. Called by surf's `serve`. |
|
||||
| `cooler.Handle` | What `cooler.Install` set up. |
|
||||
| `cooler.Handle.Cache` | The Cache `cooler.Install` published or found. |
|
||||
| `cooler.Handle.Close` | Closes the Redis client `cooler.Install` opened, if any. |
|
||||
| `cooler.Handle.Close` | Waits for the site-cache purges queued on the purger `cooler.Install` published (up to `cooler.SiteCachePurgeTimeout` plus one second), then closes the Redis client `cooler.Install` opened, if any. |
|
||||
| `cooler.Handle.RateLimitRedis` | Reports whether `http.rate_limit.store` selects the Redis store. |
|
||||
| `cooler.Handle.RateLimitStore` | Returns the Redis rate-limit store with the given fallback, or the fallback itself when Redis is not selected. |
|
||||
| `cooler.Attempter` | One atomic fixed-window admission; the method set of `surf.Store`. |
|
||||
@@ -175,9 +175,10 @@ func AllowExport(ctx context.Context, app *backpack.App, fallback cooler.Attempt
|
||||
| `cooler.SiteCachePurger` | Sends the site-cache purge request; a nil purger does nothing. |
|
||||
| `cooler.NewSiteCachePurger` | Builds the purger from the values of `site_cache.purge_url` and `site_cache.purge_token`; both empty returns nil; errors name those keys and never the token. |
|
||||
| `cooler.NewSiteCachePurgerFor` | The same with the config keys its errors name passed in, for a plugin that reads deprecated keys of its own. |
|
||||
| `cooler.SiteCachePurger.Purge` | Sends one purge request (2 s timeout, detached from cancellation, redirects not followed) and logs the outcome; never fails. |
|
||||
| `cooler.SiteCachePurger.Purge` | Sends one purge request and blocks until it is done (2 s timeout, detached from cancellation, redirects not followed); the send the after-commit queue uses. Logs the outcome; never fails. |
|
||||
| `cooler.SiteCachePurger.Wait` | Blocks until no queued purge is pending or in flight, or until the context ends (returning its error); nil at once for a nil or idle purger. |
|
||||
| `cooler.SiteCachePurger.Endpoint` | The purge URL's host and path, for log lines. |
|
||||
| `cooler.PurgeSiteCacheAfterCommit` | Registers one purge to run after the given transaction commits (at once outside a transaction). |
|
||||
| `cooler.PurgeSiteCacheAfterCommit` | Queues one purge after the given transaction commits (at once outside a transaction), fire and forget: one request in flight per purger, later saves collapse into one follow-up. |
|
||||
| `cooler.SiteCacheFromApp` | Returns the published purger, or builds it from the framework keys and publishes it; nil when unset or invalid. |
|
||||
| `cooler.SiteCachePurgeURLKey` | `site_cache.purge_url`. |
|
||||
| `cooler.SiteCachePurgeTokenKey` | `site_cache.purge_token`. |
|
||||
|
||||
Reference in New Issue
Block a user