Discussion:
[modwsgi] Relationship between WSGIApplicationGroup and WSGIDaemonProcess
Samer Atiani
2016-09-08 18:21:46 UTC
Permalink
Greetings!

I have configuration that looks like this:

WSGIDaemonProcess example_daemon
WSGIProcessGroup example_daemon
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/example.wsgi

From the docs, the defaults for WSGIDaemonProcess is process=1 and
threads=15. However, the docs also say the following about %{GLOBAL}:

"Any WSGI applications in the global application group will always be
executed within the context of the first interpreter created by Python when
it is initialised."

Does that mean that the configuration above makes it so that there only one
interpreter for all requests? Does that consequently mean that it can only
process one request at a time?

Samer
--
You received this message because you are subscribed to the Google Groups "modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modwsgi+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at https://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.
Graham Dumpleton
2016-09-08 20:42:47 UTC
Permalink
Post by Samer Atiani
Greetings!
WSGIDaemonProcess example_daemon
WSGIProcessGroup example_daemon
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/example.wsgi
"Any WSGI applications in the global application group will always be executed within the context of the first interpreter created by Python when it is initialised."
Does that mean that the configuration above makes it so that there only one interpreter for all requests?
Where WSGIDaemonProcess had processes=1 that would be the case anyway.
Post by Samer Atiani
Does that consequently mean that it can only process one request at a time?
The total number of requests that can be handled at any one time in a daemon process group, is:

processes * threads

What the application group is about is what interpreter context the WSGI application runs in.

When you are dealing with command line Python, there is only one interpreter context (first or main interpreter context) but when using the C API as is done when embedding, you can create additional sub interpreter contexts.

These sub interpreter contexts live in the same process they are created in and provide pseudo separation between running Python applications. It isn’t perfect separation, but lets gloss over that as don’t want to go into the mechanics of it.

So normally what happens with mod_wsgi is that each WSGI application is run in a different sub interpreter context of the process handling the request. This is to keep them separate.

So if you had 3 processes and 5 threads, and two separate WSGI applications delegated to that daemon process group. Each of those 3 processes would have a copy of each WSGI application, but in two different sub interpreter contexts of each process. So still a copy in each process.

Across the two of the WSGI applications they would share the total request handler thread pool of 3*5 = 15 threads.

Thus if one WSGI application misbehaved and blocked requests and used up all 15 threads at a specific time, the other WSGI application wouldn’t be able to process requests, nor would the first either for that matter if all 15 were used.

This is why you would give each WSGI application its own daemon process group.

Now sub interpreters generally work okay, but in some cases you get third party extension modules for Python that don’t use the Python C API for threading in a way to allow them to work properly in sub interpreters. In this case you need to force them to run in the first or main interpreter context. So rather than use a sub interpreter, it would use that first interpreter created in the process much like what happens when using command line Python.

If you did this for a whole daemon process group and all the WSGI applications running in that group, it means those two WSGI applications would be forced to run in the same interpreter context. For some WSGI applications that would be bad. Django cannot do that for example. This is why a WSGI application per daemon process group is better.

So forcing use of the first or main interpreter context is to work around problems with some C extension modules for Python.

Although separate sub interpreter contexts is the default, is recommended that the use of the first interpreter context always be used when using daemon mode. You should though ensure only one WSGI application per daemon process group.

So it does not affect how many concurrent requests you can handle. For daemon process groups that is still processes*threads. Just keep in mind that the pool of Apache workers (processes or threads) still needs to be sufficient in capacity to be able to handle proxying the required number of concurrent requests through to the daemon process groups. There is no point setting up a daemon process group with capacity for 200 requests if the Apache workers can only proxy at most 100 at any one time.

Graham
--
You received this message because you are subscribed to the Google Groups "modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modwsgi+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at https://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.
Samer Atiani
2016-09-12 17:55:56 UTC
Permalink
Makes sense. Thank you for the detailed answer!
Post by Samer Atiani
Post by Samer Atiani
Greetings!
WSGIDaemonProcess example_daemon
WSGIProcessGroup example_daemon
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/example.wsgi
From the docs, the defaults for WSGIDaemonProcess is process=1 and
"Any WSGI applications in the global application group will always be
executed within the context of the first interpreter created by Python when
it is initialised."
Post by Samer Atiani
Does that mean that the configuration above makes it so that there only
one interpreter for all requests?
Where WSGIDaemonProcess had processes=1 that would be the case anyway.
Post by Samer Atiani
Does that consequently mean that it can only process one request at a
time?
The total number of requests that can be handled at any one time in a
processes * threads
What the application group is about is what interpreter context the WSGI
application runs in.
When you are dealing with command line Python, there is only one
interpreter context (first or main interpreter context) but when using the
C API as is done when embedding, you can create additional sub interpreter
contexts.
These sub interpreter contexts live in the same process they are created
in and provide pseudo separation between running Python applications. It
isn’t perfect separation, but lets gloss over that as don’t want to go into
the mechanics of it.
So normally what happens with mod_wsgi is that each WSGI application is
run in a different sub interpreter context of the process handling the
request. This is to keep them separate.
So if you had 3 processes and 5 threads, and two separate WSGI
applications delegated to that daemon process group. Each of those 3
processes would have a copy of each WSGI application, but in two different
sub interpreter contexts of each process. So still a copy in each process.
Across the two of the WSGI applications they would share the total request
handler thread pool of 3*5 = 15 threads.
Thus if one WSGI application misbehaved and blocked requests and used up
all 15 threads at a specific time, the other WSGI application wouldn’t be
able to process requests, nor would the first either for that matter if all
15 were used.
This is why you would give each WSGI application its own daemon process group.
Now sub interpreters generally work okay, but in some cases you get third
party extension modules for Python that don’t use the Python C API for
threading in a way to allow them to work properly in sub interpreters. In
this case you need to force them to run in the first or main interpreter
context. So rather than use a sub interpreter, it would use that first
interpreter created in the process much like what happens when using
command line Python.
If you did this for a whole daemon process group and all the WSGI
applications running in that group, it means those two WSGI applications
would be forced to run in the same interpreter context. For some WSGI
applications that would be bad. Django cannot do that for example. This is
why a WSGI application per daemon process group is better.
So forcing use of the first or main interpreter context is to work around
problems with some C extension modules for Python.
Although separate sub interpreter contexts is the default, is recommended
that the use of the first interpreter context always be used when using
daemon mode. You should though ensure only one WSGI application per daemon
process group.
So it does not affect how many concurrent requests you can handle. For
daemon process groups that is still processes*threads. Just keep in mind
that the pool of Apache workers (processes or threads) still needs to be
sufficient in capacity to be able to handle proxying the required number of
concurrent requests through to the daemon process groups. There is no point
setting up a daemon process group with capacity for 200 requests if the
Apache workers can only proxy at most 100 at any one time.
Graham
--
You received this message because you are subscribed to the Google Groups "modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modwsgi+***@googlegroups.com.
To post to this group, send email to ***@googlegroups.com.
Visit this group at https://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.
Loading...