On Mon, 2007-06-11 at 16:13 +0000, Tarek wrote:
> Hello,
> 
> I have in one of my package, registered as an INSTALLED_APPS, a
> special global variable in the __init__.py that opens some ressources.
> 
> The problem is that the packages seems to be loaded twice, with
> __import__:
>   /Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-
> packages/django/utils/translation/trans_real.py(166)_fetch()
> -> app = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]),
> appname[p+1:])
> 
> This is OK for most of the code but in my case it leads to a problem:
> the third party app that is initialized in a global variable locks a
> file, and tries to relock it again as the __import__ is recalled:

Isn't this also problematic when multiple threads or processes import
the same file, then? There would seem to be a number of Django server
configurations (e.g. modpython and flup) where this won't work. How are
you working around those?

> 
>   File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
> python2.5/site-packages/django/core/management.py", line 1678, in
> execute_manager
>     execute_from_command_line(action_mapping, argv)
>   File
> [..]
>     default_translation = _fetch(settings.LANGUAGE_CODE)
>   File "/Library/Frameworks/Python.framework/Versions/2.5/lib/
> python2.5/site-packages/django/utils/translation/trans_real.py", line
> 166, in _fetch
>     app = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]),
> appname[p+1:])
> [..]
> xapian.DatabaseLockError: Unable to acquire database write lock on /
> Users/repos/hg.programmation-python.org/xap/data/chainon.xap: already
> locked
> --Return--
> 
> 
> My questions are:
> 
> + Is there a place where I initialize some global variables (eg
> singletons) juste once, then get them somehow ?
> Like a registery maybe

The one file you know will be imported at least once is the settings
file. But you will still need to work around the multiple import problem
because of different threads or processes importing it.

You could write a function that did each of your once-only things and
then set up a condition (file lock or creating a directory, for example)
to prevent them running again. However, graceful shutdown is then an
issue -- it may not always happen, leaving the lock in place and
preventing a successful restart. That's a general problem in these sort
of cases though. It's why "shared nothing" is one of the goals for
frameworks like Django. Synchronising non-idempotent setup and state
across threads/processes/random restarts is hard.

> 
> + Ain't this behavior buggy, since it seems to act like reload() ?

The fact that __import__() reloads the code is a feature of Python. Not
something we are really in a position to change.

It might be possible to check if the code we want is already in
sys.modules to avoid some of the reloading cases. However, there are
going to be cases when we can't avoid the reload effect, I suspect. For
example, if application foo/ has already been imported and we then want
access to foo/templatetags/ inside Django, we aren't going to be able to
avoid passing 'foo' to the __import__ statement. So it might not be
possible to completely eliminate reloads.

I think anybody relying on "import once only" semantics has to code a
bit more defensively in this case. Suggestions to improve that situation
in the form of patches would be gladly reviewed, though.

Best wishes,
Malcolm


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to