On 01/07/2014, at 10:48 PM, Ice Prince <[email protected]> wrote:

> Hello,
> Me again. I'm in satisfaction with my current configuration as quite good in 
> performance:
> Apache: prefork with 150 child processed max, wsgi daemon mode:  processes=6 
> threads=5
> 
> I have a Flask global variable:
>     app.abc = select_db(my_db) 
> 
> At the beginning (the 1st request) of a process, it takes some time to get 
> the value of app.abc cause Database progress, after that, for the sub 
> sequence requests of same process, i already have the app.abc in memory to 
> serve the threads, so it's really fast to respond.
> 
> Now, issue raise when the content in DB is changed and i need to update the 
> app.abc but i don't know how to clean app.abc of all processes in the memory. 
> Apache reload is solved problem but this is really ugly method, touch the 
> wsgi file also not help cause this global var still persist in mem.

If touching the WSGI script file doesn't help then there would have to be 
something wrong with your configuration.

If using daemon mode and the WSGI script file is touched, then on the next 
request, that should force the processes to be reloaded at that point. Nothing 
should be kept in memory and there should be a clean cutover with the next 
request always seeing any new data, with no chance of processes having 
different data cached.

Because you have multiple daemon processes, even if that is working correctly, 
there will be a delay as all the processes have to reload and you have your 
preloading which will slow that down. Long running requests can also delay 
shutdown as the full shutdown timeout may expire before the processes are 
forced to restart.

In general, as Jason pointed out, it sounds like you possibly should be using a 
memory caching system such as Redis or Memcache rather than doing in process 
caching. That way you can set expiration mechanisms or use other means to flush 
out data without needing to restart the whole application.

Another thing you might consider if using latest mod_wsgi is that daemon mode 
process now accepts a signal for a form of graceful restart.

Add potentially graceful process restart option for daemon processes
when sent a graceful restart signal. Signal is usually ``SIGUSR1`` but is
platform dependent as using same signal as Apache would use. If the
``graceful-timeout`` option had been provided to ``WSGIDaemonProcess``,
then the process will attempt graceful shutdown first based on that
timeout, otherwise normal shutdown procedure used as if received a
``SIGTERM``.

If it isn't critical that all processes be reloaded at the same time so the 
view of the cached data is the same, then you can set 'graceful-timeout' to say 
5 seconds and then cycle through each daemon process and send them SIGUSR1 in 
turn. You can identify the processes more easily by using the 'display-name' 
option to WSGIDaemonProcess and giving them a unique name. That name can then 
be picked up by 'ps' command (on most systems) to work out the process IDs.

Now what is meant by graceful here is that it gives the process an extended 
amount of time to finish any current requests, albeit still allowing new ones 
to keep being served at the same time. In other words, as soon as the process 
is not handling any requests within that graceful shutdown time window, it will 
then go into proper shutdown mode, no longer accepting any new requests and 
exiting so the process is restarted. If the graceful timeout expires, then it 
performs the more brutal restart which can cause current requests to be 
interrupted, although the normal shutdown timeout still gives a further 3 
seconds for those requests to still complete.

If you have multiple processes, this allows you to cycle through processes 
restarting each in turn, reducing the chances that requests will back up as 
some process is likely still handling requests.

At the same time as doing this, would also suggest looking at application 
preloading. This can be used to ensure that the WSGI script file is loaded 
before the process starts accepting any new requests. That way if preloading at 
module scope, that will not delay the first request as the process will not now 
only lazily load the WSGI script file on the first request. Therefore, the 
request will instead be accepted by another process which is ready and has 
already preloaded the WSGi script file and your data.

To perform preloading of the WSGi script on process start, before the process 
starts accepting requests, don't use WSGIProcessGroup and WSGIApplicationGroup. 
Instead give these on the WSGIScriptAlias line as:

  WSGIScriptAlias / /some/path/file.wsgi process-group=mygroup 
application-group=%{GLOBAL} processes=6 threads=5 graceful-timeout=5 
display-name=%{GROUP}

With both supplied, mod_wsgi will know in advance which context the WSGi script 
will run in and so will preload it on process start.

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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.

Reply via email to