random seed identical among preforked FastCGI instances
|Reported by:||Owned by:||nobody|
|Severity:||Normal||Keywords:||random seed fastcgi fcgi prefork|
|Cc:||flori@…, mmitar@…||Triage Stage:||Accepted|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
While writing a basic captcha module, I was encountering a lot of duplicate strings of "random" text that I could not explain. Then I remembered seeing this comment on a separate session issue: http://code.djangoproject.com/ticket/1180#comment:20
Based on that info, I setup some extra logging, and it did appear that each of my FastCGI threads were producing identical random values. I was specifically using a call like this: random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ'). It's possible other random methods are not affected, I was only interested in that one. It seems the random seed is set prior to the fork, and each forked process thereafter produces identical random output as a result.
In my setup, I run manage.py with method=prefork, runfcgi, and a static number of processes. This is on an Ubuntu Gutsy AMD 64-bit (on Xen) with Python 2.5.1. I'm currently running against SVN Django, revision 7049.
My workaround was to add a middleware class with an init function that sets the random seed. This gets called at "startup" in each of the new FCGI processes, giving them unique random output. Obviously not ideal, but it gets the job done in my case.
import logging, logging.config import os, random, time class ReseedRandom(object): def __init__(self): logging.debug("setting new random seed for this process") random.seed("%d%s" % (os.getpid(), time.ctime()))
It would be much cleaner if the manage.py FCGI launcher could seed its random number generator AFTER the fork occurs, rather than before (or not at all, as the case may be).
Change History (16)
comment:11 Changed 6 years ago by
|Patch needs improvement:||set|