[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