Forum OpenACS Q&A: ns_shutdown and ns_atshutdown replacements

because of the problems with these calls when nsd is under load, detailed here, I wrote replacements. It has the added benefit (besides not hanging :) of allowing you to ns_return something besides the default error message after you stop accepting connections while your atshutdown stuff is running. In case anyone else would find them useful, here they are. No backslashes and no <s so I should be on bboard's good side except for a few retarded linebreaks. :P

where ad-security registers its filters, add


    nsv_set ad_security mutex [ns_mutex create]
    nsv_set ad_security active_p 1
    nsv_set ad_security at_shutdown [list]
    ad_register_filter -critical t -priority 0 preauth * /* 
ad_abort_if_shutting_down
everything else can be added anywhere; I just tacked it on the end of ad-security

proc_doc ad_atshutdown {script} {
    just like ns_shutdown except it works even when site is loaded
    (and ad_abort_if_shutting down allows us to serve something 
besides an error msg
    while we run our atshutdown stuff.  some cache flushing may take 
a while.)
} {
    ns_mutex lock [nsv_get ad_security mutex]
    set l [nsv_get ad_security at_shutdown]
    nsv_set ad_security at_shutdown [lappend $l $script]
    ns_mutex unlock [nsv_get ad_security mutex]
}

proc_doc ad_shutdown {} {
    shuts down server gracefully; ns_shutdown can hang, so we won't 
use it.
} {
    nsv_set ad_security active_p 0 ;# no more requests processed

    foreach script [nsv_get ad_security at_shutdown] {
        eval $script
    }

    # this assumes you have a script to kill all the nsd pids, like 
aD's,
    # in the hardcoded location
    # (ns_kill [ns_info pid] 9 doesn't work, probably cuz it only 
kills one pid
    # -- it does die very quickly, but a thread still has control of 
the nscp
    # port long enough to screw everything up when init restarts nsd.
    # using the following script kills everything at once so the 
restart is happy.
    exec /usr/local/bin/restart-aolserver.pl [ns_info server] KILL
}

proc_doc ad_abort_if_shutting_down { conn args why } {
    our filter.
    only allows conn to proceed if we aren't shutting down via 
ad_shutdown
} {
    if [nsv_get ad_security active_p] {
        return filter_ok
    }
    ns_return 200 text/html "Server is restarting.  Check back in a 
couple minutes."
    return filter_return
}