[mod_python] concurrent connections

Graham Dumpleton grahamd at dscpl.com.au
Tue Jul 25 00:20:01 EDT 2006


Jay Knight wrote ..
> 1.  I was just using firefox when I noticed this behavior.
> 2. 2.0.58
> 3. looks like it's prefork
> 4. StartServers            2
>     MinSpareServers         1
>     MaxSpareServers         5
>     MaxClients             64
>     MaxRequestsPerChild  4000
> 5. 3.1.4
> 
> I just now noticed that this behavior only happens when the same URL
> is called.  For example, if I have a file test.py in this directory,
> and call its url, the mptest.py is still used because it's defined as
> the handler.  If I try to load mptest.py and test.py at the same time,
> they will both return 5 seconds later, but calling the same URL twice
> will invoke the problem.
> 
> Everything else running on this server has no trouble with
> concurrancy, just these scripts, so I'm guessing it's not apache
> itself.
> 
> Any more ideas?

As I suggested, use 'ab' from the command line to test it and take Firefox
out of the picture. It may be the browser. Also suggest put some logging
in the handler so you can see at what point things are executed.

For logging use something like:

from mod_python import apache
import time

def handler(req):
  apache.log_error('handler 1 %s %f' % (req.uri, time.time()))
  time.sleep(5.0)
  req.content_type = 'text/plain'
  req.write('hello')
  apache.log_error('handler 2 %s %f' % (req.uri, time.time()))
  return apache.OK

In the Apache error log you would then see:

[Tue Jul 25 14:16:09 2006] [error] handler 1 /~grahamd/mptest.py 1153800969.010983
[Tue Jul 25 14:16:09 2006] [error] handler 1 /~grahamd/mptest.py 1153800969.015628
[Tue Jul 25 14:16:09 2006] [error] handler 1 /~grahamd/mptest.py 1153800969.105815
[Tue Jul 25 14:16:09 2006] [error] handler 1 /~grahamd/mptest.py 1153800969.114988
[Tue Jul 25 14:16:09 2006] [error] handler 1 /~grahamd/mptest.py 1153800969.118962
[Tue Jul 25 14:16:14 2006] [error] handler 2 /~grahamd/mptest.py 1153800974.011605
[Tue Jul 25 14:16:14 2006] [error] handler 2 /~grahamd/mptest.py 1153800974.016111
[Tue Jul 25 14:16:14 2006] [error] handler 2 /~grahamd/mptest.py 1153800974.106389
[Tue Jul 25 14:16:14 2006] [error] handler 2 /~grahamd/mptest.py 1153800974.116681
[Tue Jul 25 14:16:14 2006] [error] handler 2 /~grahamd/mptest.py 1153800974.125160

I generated this with:

/usr/local/apache-2.0/bin/ab -n 5 -c 5 http://localhost:8082/~grahamd/mptest.py

The output from 'ab' was:

This is ApacheBench, Version 1.3d <$Revision: 1.73 $> apache-1.3
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 1997-2005 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Apache/2.2.2
Server Hostname:        localhost
Server Port:            8082

Document Path:          /~grahamd/mptest.py
Document Length:        5 bytes

Concurrency Level:      5
Time taken for tests:   5.123478 seconds
Complete requests:      5
Failed requests:        0
Write errors:           0
Total transferred:      890 bytes
HTML transferred:       25 bytes
Requests per second:    0.98 [#/sec] (mean)
Time per request:       5123.478 [ms] (mean)
Time per request:       1024.696 [ms] (mean, across all concurrent requests)
Transfer rate:          0.00 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:  5008 5071  56.7   5108    5122
Waiting:     5007 5070  56.4   5107    5121
Total:       5008 5071  56.7   5108    5122

Percentage of the requests served within a certain time (ms)
  50%   5103
  66%   5113
  75%   5113
  80%   5122
  90%   5122
  95%   5122
  98%   5122
  99%   5122
 100%   5122 (longest request)

See how time take for tests is 5 seconds and mean time per request is
also 5 seconds.

Now trying:

  /usr/local/apache-2.2/bin/ab -n 10 -c 5 http://localhost:8082/~grahamd/mptest.py

I get:

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 1997-2005 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient).....done


Server Software:        Apache/2.2.2
Server Hostname:        localhost
Server Port:            8082

Document Path:          /~grahamd/mptest.py
Document Length:        5 bytes

Concurrency Level:      5
Time taken for tests:   10.68433 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      1780 bytes
HTML transferred:       50 bytes
Requests per second:    0.99 [#/sec] (mean)
Time per request:       5034.216 [ms] (mean)
Time per request:       1006.843 [ms] (mean, across all concurrent requests)
Transfer rate:          0.10 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    9  12.4      9      34
Processing:  5005 5011   6.1   5010    5024
Waiting:     5000 5005   5.8   5006    5018
Total:       5005 5020  15.8   5019    5048

Percentage of the requests served within a certain time (ms)
  50%   5019
  66%   5022
  75%   5027
  80%   5047
  90%   5048
  95%   5048
  98%   5048
  99%   5048
 100%   5048 (longest request)

Mean time for each request is still 5 seconds, but overall test time is
10 seconds because did 10 request overall with 5 at a time. Thus
second set of 5 serialised behind the other so test itself takes twice
as long.

In summary, don't trust Firefox, use 'ab' as it will give you a more
accurate picture of what is going on.

Graham

> On 7/24/06, Graham Dumpleton <grahamd at dscpl.com.au> wrote:
> > Jay Knight wrote ..
> > > If you take the hello world example, and add a time.sleep(5) at the
> > > beginning... like this:
> > >
> > > -----
> > > import time
> > > from mod_python import apache
> > >
> > > def handler(req):
> > >     time.sleep(5)
> > >     req.content_type = "text/plain"
> > >     req.write("Hello World!")
> > >     return apache.OK
> > > -----
> > >
> > > Then request that URL twice, it seems that the second one doesn't
> > > start until the first one is completely finished, that is, I can't
> > > make them run at the same time.  (And therefore, if I started 20 at
> > > about the same time, the last one would not complete until about 100
> > > seconds later, etc)  How would I go about making them run at the same
> > > time?
> > >
> > > I've got a pretty standard mod_python install on gentoo.  The
> > > .htaccess for this directory is
> > >
> > > -----
> > > AddHandler mod_python .py
> > > PythonHandler mptest
> > > PythonDebug On
> > > -----
> > >
> > > I know this must be possible.  But I don't know if it is a
> > > configuration issue (.htaccess) or something within the code itself
> > > (manually forking stuff off to handle multiple connections? bleh).
> >
> > Apache should handle everything for you so as to allow concurrent
> > connections.
> >
> > Some questions for you.
> >
> > 1. What client are you using to create the connections and test this?
> > Are you sure it isn't the client that is serialising the requests?
> >
> > One would normally use 'ab" to do such a test. For example:
> >
> >   ab -n 10 -c 5 http://localhost/some/path
> >
> > The '-n' option says 10 requests, with '-c' saying run 5 concurrently.
> >
> > 2. What version of Apache are you using?
> >
> > 3. If Apache 2.X, what MPM is compiled in to it, worker or prefork?
> >
> > You can determine this by going:
> >
> >   httpd -l
> >
> > and then looking for either 'worker.c' or 'prefork.c' file being compiled
> in.
> >
> > 4. How is Apache configured in respect of number of child processes
> > to create etc.
> >
> > For example:
> >
> > <IfModule mpm_prefork_module>
> >     StartServers          5
> >     MinSpareServers       5
> >     MaxSpareServers      10
> >     MaxClients          150
> >     MaxRequestsPerChild   0
> > </IfModule>
> >
> > or:
> >
> > <IfModule mpm_worker_module>
> >     StartServers          2
> >     MaxClients          150
> >     MinSpareThreads      25
> >     MaxSpareThreads      75
> >     ThreadsPerChild      25
> >     MaxRequestsPerChild   0
> > </IfModule>
> >
> > 5. What version of mod_python are you using?
> >
> > Graham
> >
> _______________________________________________
> Mod_python mailing list
> Mod_python at modpython.org
> http://mailman.modpython.org/mailman/listinfo/mod_python


More information about the Mod_python mailing list