Code

Opened 6 years ago

Closed 17 months 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: master
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 6 years ago.

Download all attachments as: .zip

Change History (12)

Changed 6 years ago by durdinator

comment:1 Changed 6 years ago by durdinator

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 Changed 6 years ago by grahamd

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 Changed 6 years ago by durdinator

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 Changed 6 years ago by Simon Greenhill

  • Patch needs improvement set
  • Triage Stage changed from Unreviewed to Accepted

comment:5 Changed 6 years ago by korpios

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

comment:6 Changed 6 years ago by korpios

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

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

comment:7 Changed 6 years ago by anonymous

  • Cc nreilly@… added

comment:8 Changed 3 years ago by lukeplant

  • Severity set to Normal
  • Type set to Bug

comment:9 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:10 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:11 Changed 17 months ago by aaugustin

  • Resolution set to invalid
  • Status changed from new to closed

Support for mod_python was removed in Django 1.5.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.