Anyone actually get SignalBeforeTerminateSeconds working? [Answered]RSS

12 replies

Last post May 13, 2010 01:18 PM by don.raman

  • Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 12:24 PM|tony_ser|LINK

    Using Vista 64 IIS7 with the update (KB980363). I have set SignalBeforeTerminateSeconds and put break point in PHP source and saw php-cgi.exe gets the event. But I am not sure if php-cgi.exe actually does anything with it. And the result is it won't exit so IIS will just wait n seconds before terminating it. In other word, setting SignalBeforeTerminateSeconds to 15 simply make IIS delay 15 seconds (all the time) before killing the process. Is there anything I need to set on the PHP side for it to react to the _FCGI_SHUTDOWN_EVENT_ and exit. Thanks!
  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 01:15 PM|don.raman|LINK

    Hi,

    Whatever you are seeing is the intended behaviour. When SignalBeforeTerminateSeconds is set to a value greater than 0, IIS sends _FCGI_SHUTDOWN_EVENT to the child process before terminating them forcibly and wait for seconds configured as part of SignalBeforeTerminateSeconds. This gives the FastCGI dying process to exit themselves cleanly. For example if a FastCGI process (here php-cgi.exe) wants to do some cleanup like close some open handle, give back some taken resource, free some shared memory etc. can now do the cleanup before dying. So the cleanup code has to be written by an application developer. In a nutshell, do whatever you want to do as IIS now gives you a way to do things before forcibly shutting down the FastCGI process.

    Hope this explain things. Treat this as kind of signal. IIS is giving you signal and you as an application developer needs to write your own signal handler to deal with this signal if required.

    Thanks,

    Don.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 01:46 PM|tony_ser|LINK

    Hi,

    I understand that part (I think) but I thought the child process is supposed to exit when they are finish cleaning up so that IIS does need to wait for the max time. I was expecting SignalBeforeTerminateSeconds specify the maximum wait time before force kill. And if the FastCGI process cleanup sooner, IIS does not have to wait that long.

    Or is it designed to alway wait that long?

    Thanks!

    Tony

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 01:52 PM|ksingla|LINK

    If process exits early, FastCGI will detect that and short circuit the wait.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 01:52 PM|don.raman|LINK

    Hi,

    IIS will wait for specified seconds if process doesn't go away. How is IIS going to know that you are done with the cleanup? There is no callback to IIS from FastCGI process that 'I am done and so terminate me'. Rather just call PHP function die or exit after you are done with clean-up code and the php-cgi.exe will go away. And you will not need to wait for seconds specified. This feature is intended to give application user a control to terminate their PHP process rather than IIS forcibly terminating them.

    Thanks,

    Don.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 02:05 PM|tony_ser|LINK

    Hi,

    Perfect. Now that we straighten out this part. We can go back to my original question.

    That is "has anyone able to get SignalBeforeTerminateSeconds working with php-cgi.exe." (Sorry, I should have mentioned php-cgi.exe in the subject)

    What I mean is anyone able to setup SignalBeforeTerminateSeconds=15 and saw php-cgi.exe exit before 15 seconds and IIS does not have to wait full 15 seconds.

    I know SignalBeforeTerminateSeconds is a FastCGI feature, how a FastCGI process (php-cgi.exe in this case) behaves is beyond the control of FastCGI module itself. But given PHP is probably the most commong FastCGI process, I am just wondering if someone actually get it working in this setup. Because I cannot get php-cgi.exe to exit earlier.

    Thanks!

    Tony

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 02:14 PM|don.raman|LINK

    Hi,

    Can you share a sample piece of code so that we know what are you trying to do?

    Thanks,

    Don.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 03:02 PM|tony_ser|LINK

    Sure, but actually nothing special. Default installation of PHP 5.2.12 FastCGI mode

    Here is the fastcgi section in applicationHost.config

            <fastCgi>
                <application fullPath="C:\Program Files (x86)\PHP\php-cgi.exe" monitorChangesTo="php.ini" maxInstances="4" idleTimeout="6000" activityTimeout="600" requestTimeout="90" instanceMaxRequests="10000" signalBeforeTerminateSeconds="30" protocol="NamedPipe" flushNamedPipe="false">
                    <environmentVariables>
                        <environmentVariable name="PHPRC" value="C:\Program Files (x86)\PHP\" />
                    </environmentVariables>
                </application>
            </fastCgi> 

     

    Just create a php page with <? phpinfo(); ?>

    Browse the page and then either do a "iisreset" or add a comment to php.ini save it to trigger the recycle due to "monitorChangesTo"

    Watch the php-cgi.exe in taskmanager and notice they won't exit until 30 seconds.

    I also loaded the debug symbol and php source.

    In sapi/cgi/fastcgi.c

    static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg)

    {

    HANDLE shutdown_event = (HANDLE) arg;

    WaitForSingleObject(shutdown_event, INFINITE);

    in_shutdown = 1;

    return 0;

    }

    The event did get triggered but php-cgi.exe did not exit itself.

    The reason we are testing this is we implemented a php extension and we do have resources that need to cleanup on shutdown. Ever since we switched to FastCGI model we notice the force kill and have made request on iis and php forum for a solution that allow proper cleanup. SignalBeforeTerminateSeconds sounds perfect and that is when we try it out and notice this FIX delay behaviour with just the default php-cgi.exe without our extension.

    Also notice that even php-cgi.exe gets the event, within that 30 seconds, PHP_MSHUTDOWN_FUNCTION of any extension is not being called. Again, not with our extension, just the default php_date, the PHP_MSHUTDOWN_FUNCTION did not get called. But that is a seperate issue.

    Thanks!

    Tony

     

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 05:53 PM|don.raman|LINK

    Hi Tony,

    tony_ser

    The event did get triggered but php-cgi.exe did not exit itself.

    Why do you expect that mere trigger of the event will exit php-cgi.exe? The event is just a signal from IIS FastCGI that I am going to forcibly kill you after 'n' number of seconds as configured in property signalBeforeTerminateSeconds, so do all the clean-up required and stay (so that IIS FastCGI can kill the php-cgi.exe) or call an exit in which case php-cgi.exe gets killed itself without waiting for 'n' seconds. I would say just do the clea-up and let IIS FastCGI actually exiting the php-cgi.exe. The reason is if your extension does a force exit, other extension may not get a chance to clean-up properly.

    The other question is how did you know that event got triggered? The reason you are seeing a 30 seconds delay is because IIS FastCGI DLL is waiting for 30 seconds as configured before forcibly killing the process. This doesn't guarantee that event is generated unless you listen to it and ensure that event is indeed generated.

    tony_ser

    The reason we are testing this is we implemented a php extension and we do have resources that need to cleanup on shutdown.

    Look IIS has just sent the event. This event is not going to trigger php-cgi.exe exit automatically and hence your extension shutdown function will never get called. Also after configured 'n' seconds a forceful exit of php-cgi.exe will be called and again your extension shutdown function will not be called. Because of this reason setting signalBeforeTerminateSeconds to 30 is delaying your problem for another 30 seconds.

    I am no expert at event handling and all but here is what you will need to do in order to handle this in your extension:

    • <div mce_keep="true">In your extension initialization function (I believe that's called PHP_MINIT_FUNCTION) get the value of environment variable _FCGI_SHUTDOWN_EVENT_.</div>
    • <div mce_keep="true">The value of this environment variable will be handle to the event which IIS will signal before doing an abrupt/forceful shutdown of php-cgi.exe.</div>
    • <div mce_keep="true">Listen to this event handle. Once the event is signalled do the clean-up.</div>

    Hopefully this helps. And again thanks for enlightening me a bit too :).

    Regards,

    Don.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 12, 2010 09:06 PM|ksingla|LINK

    Looks like a bug in php-cgi.exe. PHP should trigger a shutdown and exit on receiving this event.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 13, 2010 12:23 AM|tony_ser|LINK

    don.raman

    Why do you expect that mere trigger of the event will exit php-cgi.exe?...The reason is if your extension does a force exit, other extension may not get a chance to clean-up properly.

    You are absolutely right. Extensions should not force exit. I was expecting php-cgi.exe (since it receive event instead of being force killed) now has a chance to call PHP_MSHUTDOWN_FUNCTION of each loaded extension and then exit.

    don.raman

    The other question is how did you know that event got triggered?

    Because I put a break point in the thread in php-cgi.exe and the WaitForSingleObject call monitoring the shutdown event returned.

    Your suggestion of listening to the event in my extension make sense and it is exactly what I think I will need to do.

    But it does not change the fact that anytime SignalBeforeTerminateSeconds is setup, IIS must always wait that fix time before exit. Again, with php-cgi.exe the most commonly used FastCGI process, I was just surprised with the behaviour. I thought I may have miss some setup procedure. Hence, my subject "anyone actually get SignalBeforeTerminateSeconds working (with php-cgi.exe)", hoping if someone has experience on this can shed some light.

    Appreciate your points and suggestions!

    Thanks!

    Tony

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 13, 2010 12:30 PM|don.raman|LINK

    As my developer suggested this seems like a bug in php-cgi.exe. I am talking to him. I will update you with the findings and further action.

    Thanks for reporting it.

    Regards,

    Don.

  • Re: Anyone actually get SignalBeforeTerminateSeconds working?

    May 13, 2010 01:18 PM|don.raman|LINK

    Hi,

    php-cgi.exe doesn't handle this appropriately. So this feature will not work with php-cgi.exe. In order to have this feature work with php-cgi.exe a fix is required in PHP code.

    So answer to your original question is, signal before terminate will not work with php-cgi.exe as a FastCGI process.

    Thanks,

    Don.