Proposal: PSGI environment cleanup handlers
Clone this wiki locally
Summary: Allow middleware and framework authors to register cleanup handlers that get called back once a request is complete.
In CGI and mod_perl, there's been a traditional technique where a main program flushes the output and finishes rendering the page on the web browsers, and then run the tasks that could take a long time. It is often called "poor man's background job processing" because it allows you to run a task without making clients wait for the job to be complete.
print "Content-Type: text/plain\n\n"; print "Hello"; close STDOUT; # this ensures flushing the whole page long_running_task();
These handlers can also be used to free some resources such as temporary files, or resetting random seeds.
- Both of them rely on the lifetime of
$envwhich is not specified in the PSGI specification
- It doesn't work as expected in CGI and mod_perl environment since the callback handlers get called before a request is complete. (i.e. it will most likely block browsers)
- The callback handlers can't safely use
$envsince that will introduce circular reference. You could use weak reference to avoid that.
- Web application frameworks need to depend on such middleware (like Middleware::Cleanup) to implement the cleanup handler, which may not be desired. That was the reason for the patch to add it as a utility function inside Plack::Util, but that still lets app developers depend on Plack anyway.
Introduce a new PSGI environment variables
psgix.cleanup.handlers, to probe the capabilities of running cleanup handlers and also let applications/middleware to register callbacks to be called once a request is complete. They will be specified as follows:
psgix.cleanup- A boolean flag whether a PSGI server supports cleanup handlers. Absence of the key assumes false (i.e. unsupported). Middleware and applications MUST check this key before utilizing the cleanup handlers.
psgix.cleanup.handlers- Array reference to stack callback handlers. This reference SHOULD be initialized as an empty array reference by the servers. Applications can register the callbacks by simply push()ing a code reference to this array reference. Callbacks will be called once a request is complete, and it will receive
$envas its first argument, and return value of the callbacks will be simply ignored. An exception thrown inside callbacks MAY also be ignored.
For most servers the implementation is straightforward, calling the callbacks once a request is complete. For CGI handler we can close STDOUT before doing so, and mod_perl handlers can use
If the server also supports
psgix.harakiri, it SHOULD implement in a way that cleanup handlers run before harakiri checker, so that the cleanup handlers can commit the harakiri flag.
- The functionalities of cleanup handlers and streaming handlers are very similar, while the intent of them can be made very clear.
- cleanup handlers may not have access to all elements in the PSGI env, such as
- Middleware for exception handling or logging handlers probably doesn't work inside cleanup handlers.
Comments to https://github.com/plack/psgi-specs/issues/18
- uwsgi in the 1.3 branch