Opened 16 years ago

Closed 11 years ago

#7062 closed Bug (invalid)

Multiple projects with different TIME_ZONE settings under mod_python can cause unexpected date/time behaviour

Reported by: durdinator Owned by: nobody
Component: Core (Other) Version: dev
Severity: Normal Keywords: mod_python time timezone
Cc: me@…, nreilly@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

When running Django under mod_python, if there are multiple projects running with different TIME_ZONE settings, this can under some circumstances lead to the time zone (and hence the value returned by datetime.datetime.now()) being different for subsequent requests to the same URL.

We encountered this problem running Apache 2.0 with the prefork MPM, with 10 subprocesses. While most of the numerous Django projects on the server had TIME_ZONE = 'Europe/London' in the settings module, two had inadvertently been left with TIME_ZONE = 'America/Chicago'. After investigating a problem where a time-based query would return unexpectedly different results for repeated requests, we found that datetime.datetime.now() was mostly returning the local time value (10.05 am), but occasionally returning the wrong time (4.05 am). This 6 hour difference, not coincidentally, is the current difference between the America/Chicago and Europe/London time zones. Another instance of this problem was described in http://groups.google.com/group/django-users/browse_thread/thread/b2f8722f58b270fd/

Since the environment is maintained for each Apache subprocess, modifying it via os.environ in one subinterpreter causes the modified environment to be visible in other subinterpreters, which may be serving a different site. This causes a problem at present, as os.environ['TZ'] is set only once per project, when the settings are first loaded: http://code.djangoproject.com/browser/django/trunk/django/conf/__init__.py#L116

If the TZ environment variable were set per request (as is done with DJANGO_SETTINGS_MODULE and other environment variables passed through from the apache config via SetEnv commands), then the correct time zone setting would be available for each project. I have attached a patch against SVN HEAD to do this in the mod_python handler.

Until this is corrected, a workaround is:

  • Ensure that all django projects running under mod_python are using the same TIME_ZONE setting
  • Or if different time zones are required, then ensure that the apache config uses SetEnv to set the correct TZ variable for every project.

Attachments (1)

patch_tz.diff (908 bytes ) - added by durdinator 16 years ago.

Download all attachments as: .zip

Change History (12)

by durdinator, 16 years ago

Attachment: patch_tz.diff added

comment:1 by durdinator, 16 years ago

It is possible that a similar patch would need to be applied to http://code.djangoproject.com/browser/django/trunk/django/core/handlers/modpython.py, but I am not sure when that handler would get called relative to the core handler.

comment:2 by Graham Dumpleton, 16 years ago

Setting TZ per request will not necessarily help. This is because it isn't the TZ value from os.environ that is necessarily the problem but the TZ variable returned by C getenv() function as it is this which is used by C library time functions.

Although when os.environ is updated, C environment variables are also updated, doing this per request isn't going to help and will only result in thread race conditions when done in a multithread Apache MPM. The results therefore may even be more unpredictable.

The only way you can safely run distinct Django instances with different time zone settings is to run them in separate processes using something like mod_wsgi daemon mode or fastcgi.

comment:3 by durdinator, 16 years ago

No, setting the environment variables per request obviously won't help if using the threaded MPM; but Django shouldn't be used with that anyway; see http://www.djangoproject.com/documentation/modpython/ for more on that.

However, setting it per request and calling time.tzset() (as the patch does) will work with the prefork MPM.

comment:4 by Simon Greenhill, 16 years ago

Patch needs improvement: set
Triage Stage: UnreviewedAccepted

comment:5 by korpios, 16 years ago

Check out #2626; if time zone handling is done at the Field level, these problems go away.

comment:6 by korpios, 16 years ago

This is solved by DateTimeZoneField in Bulbs; see my comment:

http://code.djangoproject.com/ticket/2626#comment:13

comment:7 by anonymous, 16 years ago

Cc: nreilly@… added

comment:8 by Luke Plant, 13 years ago

Severity: Normal
Type: Bug

comment:9 by Aymeric Augustin, 12 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:10 by Aymeric Augustin, 12 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:11 by Aymeric Augustin, 11 years ago

Resolution: invalid
Status: newclosed

Support for mod_python was removed in Django 1.5.

Note: See TracTickets for help on using tickets.
Back to Top