handler: serialize dynamic request context
ober
e335f1ba871aae238684f26684d9a825349416ab
--- a/sinatra/handler.ss +++ b/sinatra/handler.ss @@ -1,5 +1,9 @@ (import (std text json) (std sugar) + (rename (only (std misc thread) make-mutex mutex-lock! mutex-unlock!) + (make-mutex sinatra-make-mutex) + (mutex-lock! sinatra-mutex-lock!) + (mutex-unlock! sinatra-mutex-unlock!)) (only (std secmon telemetry) secmon-telemetry-from-env secmon-telemetry-emit!) @@ -18,12 +22,24 @@ (export sinatra-handler) +(def *sinatra-handler-context-mutex* (sinatra-make-mutex)) + ;; Create an httpd handler function for the given sinatra app. ;; Returns (lambda (req) ...) suitable for Jerboa std/net/httpd. (def (sinatra-handler app) (let ((base-handler (make-base-handler app)) (mw-list (app-middleware app))) - (compose-middleware mw-list base-handler))) + (let ((handler (compose-middleware mw-list base-handler))) + (lambda (req) + ;; Chez dynamic parameters used for request context are not isolated + ;; reliably across simultaneous raw HTTP worker threads. Keep request + ;; context deterministic; expensive preprocessing runs in separate + ;; worker processes and all normal route results are cached. + (sinatra-mutex-lock! *sinatra-handler-context-mutex*) + (try + (handler req) + (finally + (sinatra-mutex-unlock! *sinatra-handler-context-mutex*))))))) ;; secmon daemon telemetry