[Catalyst] [PATCH] [RFC] Seed the RNG in Catalyst::Engine::FastCGI
Andrew Rodland
arodland at comcast.net
Mon Feb 2 23:09:21 GMT 2009
Due to the way FastCGI does its business, when running as an "external"
FastCGI, the perl interpreter and the Catalyst app are initialized before the
FCGI process manager does its forking. Since modern versions of Perl seed
rand() "eagerly" on startup, this leads to all of the FastCGI children
inheriting the same RNG state, and very nonrandom behavior (such as CAPTCHAs
that appear to get "stuck").
I've thought over the problem and decided that the only appropriate place for
a fix is in Engine::FastCGI. A srand anyplace else (including the app code)
would run either too early (not solving the "shared state" problem) or too
late (re-seeding on every request is Bad.)
Attached is a patch that does an srand in each child immediately after
invoking pm_manage, if we are running our own process manager. I can't think
at the moment how to write a test for it, but a behavior test shows that it
completely solved the randomness problem on my end, and I ran an instrumented
version to make sure that it's not srand'ing more than once per child -- it's
not. Patch applies against Catalyst-Runtime/5.80/trunk and
Catalyst-Runtime/5.70/trunk (with negligible fuzz).
Index: lib/Catalyst/Engine/FastCGI.pm
===================================================================
--- lib/Catalyst/Engine/FastCGI.pm (revision 9173)
+++ lib/Catalyst/Engine/FastCGI.pm (working copy)
@@ -130,6 +130,8 @@
$self->daemon_detach() if $options->{detach};
$proc_manager->pm_manage();
+ # Give each child its own RNG state.
+ srand;
}
elsif ( $options->{detach} ) {
$self->daemon_detach();
More information about the Catalyst
mailing list