From 60a7a00257396df0cc90b73b075e5e2b5b6244ba Mon Sep 17 00:00:00 2001 From: Carl Jackson Date: Sun, 27 Apr 2014 00:37:33 +0200 Subject: [PATCH] Better comments around middleware stack caching --- web/middleware.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/web/middleware.go b/web/middleware.go index 12c6eae..f9e7963 100644 --- a/web/middleware.go +++ b/web/middleware.go @@ -22,10 +22,23 @@ type mStack struct { router Handler } -// Constructing a middleware stack involves a lot of allocations: at the very -// least each layer will have to close over the layer after (inside) it, and -// perhaps a context object. Instead of doing this on every request, let's cache -// fully assembled middleware stacks (the "c" stands for "cached"). +/* +Constructing a middleware stack involves a lot of allocations: at the very least +each layer will have to close over the layer after (inside) it, and perhaps a +context object. Instead of doing this on every request, let's cache fully +assembled middleware stacks (the "c" stands for "cached"). + +A lot of the complexity here (in particular the "pool" parameter, and the +behavior of release() and invalidate() below) is due to the fact that when the +middleware stack is mutated we need to create a "cache barrier," where no +cStack created before the middleware stack mutation is returned to the active +cache pool (and is therefore eligible for subsequent reuse). The way we do this +is a bit ugly: each cStack maintains a pointer to the pool it originally came +from, and will only return itself to that pool. If the mStack's pool has been +rotated since then (meaning that this cStack is invalid), it will either try +(and likely fail) to insert itself into the stale pool, or it will drop the +cStack on the floor. +*/ type cStack struct { C m http.Handler