2009/7/20 Graham Dumpleton <[email protected]>:
> 2009/7/20 Graham Dumpleton <[email protected]>:
>> 2009/7/20 Malcolm <[email protected]>:
>>>
>>> Hello,
>>>
>>> I am using mod_wsgi 2.3 with Apache 2.2.11 on Ubuntu 9.04.
>>>
>>> I seem to be having problems where the code I put in on of my WSGI
>>> application files, (django.wsgi) is affecting the (sub) interpreters
>>> of other WSGI applications.
>>>
>>> Here is the relevant part of the django.wsgi file:
>>> ----------
>>> ...
>>> import warnings
>>> warnings.filterwarnings(action="ignore",
>>>    message="^the sets module is deprecated$",
>>> category=DeprecationWarning,
>>>    module="MySQLdb", lineno=34)
>>>
>>> # Determine the absolute path of the Django project directory that
>>> contains
>>> # this
>>> project.
>>> ...
>>>
>>> # If the Django project directory is not in the Python path, add
>>> it.
>>> ...
>>>
>>> os.environ['DJANGO_SETTINGS_MODULE'] = DJANGO_PROJ + '.settings'
>>>
>>> import django.core.handlers.wsgi
>>> application = django.core.handlers.wsgi.WSGIHandler()
>>> ----------
>>>
>>> In the above WSGI application file, I suppress a warning emitted by a
>>> particular module. I expected this warning to be suppressed only for
>>> this one WSGI application, but this is not the case. Say I go to /
>>> site1 where the WSGI application file suppresses the warning, then
>>> sure enough, there will be no warning in the Apache error log.
>>> However, if after visiting that WSGI application, I now go to /site2
>>> (another WSGI application that doesn't have that warning suppressed),
>>> the warning does not show up.
>>>
>>> Yet, if I restart Apache and visit /site2 first, the warning will
>>> appear in the log.
>>>
>>> I am running mod_wsgi in daemon mode with multiple WSGI applications.
>>> All the applications are running within the same process group;
>>> however, I can change this if I need to. I am using the Apache prefork
>>> MPM, and I have only one virtual host.
>>>
>>> I know this problem seems small and insignificant, since it is just
>>> affecting spam output to the Apache error log. However, it signals a
>>> larger problem for me: it means that my WSGI applications are somehow
>>> sharing state, which I don't want.
>>
>> The separation between sub interpreters isn't always perfect. If a C
>> extension module is used in implementing a Python module isn't
>> implemented correctly so as to separate data for different sub
>> interpreters properly, you can have issues.
>>
>> In this case though, we are talking about a core Python module and for
>> it I suspect it is operating on the Python core and so all
>> interpreters within the process and not just the one the module was
>> used from are affected. A quick look at the code shows:
>>
>> try:
>>    from _warnings import (filters, default_action, once_registry,
>>                            warn, warn_explicit)
>>    defaultaction = default_action
>>    onceregistry = once_registry
>>    _warnings_defaults = True
>> except ImportError:
>>    filters = []
>>    defaultaction = "default"
>>    onceregistry = {}
>>
>> So, what it does is try and import 'filters' from C extension module
>> _warnings. That value is a list and is actually a reference to a
>> global static C variable. As such, the same list will be imported into
>> all sub interpreters and changes made in one sub interpreter will
>> change what happens in other sub interpreters.
>>
>> This sharing of data between sub interpreters is actually usually not
>> a good thing to do and so am surprised to see this. I will have to do
>> a bit more research on this and post to the Python list asking about
>> why it is this way since it doesn't provide proper isolation for sub
>> interpreters.
>>
>> BTW, in mod_wsgi 3.0, you can use the WSGIPythonWarnings directive to
>> control warnings from configuration file.
>>
>>  WSGIPythonWarnings ignore::DeprecationWarning::
>>
>> This is done when Python first initialised and affects all sub
>> interpreters. But then, as you have demonstrated, there is no
>> separation where control of warnings is concerned.
>>
>> Anyway, for proper separation, looks like you will need to delegate
>> each WSGI application to a different daemon process group.
>>
>> Thanks for raising this issue as I didn't know about it.
>
> The other thing you may be able to do is:
>
>  import warnings
>  warnings.filters = list(warnings.filters)
>  warnings.onceregistry = list(warnings.onceregistry)

Whoops.

  warnings.onceregistry = dict(warnings.onceregistry)

Graham

> One of my questions on Python list is why this is already being done
> with 'warnings' module.
>
> It is quite possible that C functions directly access the global
> static version of the list and doing this may short circuit something.
> Although, that is effectively what the fallback is if _warnings cannot
> be imported.
>
> Graham
>

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

Reply via email to