http://qs1969.pair.com?node_id=141665

cmilfo has asked for the wisdom of the Perl Monks concerning the following question:

I am using PerlSvc from ActiveState to write an NT Service. To use PerlSvc, the code is wrapped in a package with the main loop inside a while loop (see below).
while (ContinueRun()) { # your loop code here # sleep }
That is not a problem. The problem arises in that while the loop is sleeping, it can not be interrupted (i.e. In UNIX I can trap a signal and exit, awake, etc). Under NT (using PerlSvc), I've not found a way to do this. When a user goes to Stop the NT Service from the Services Menu, it hangs until the Stop times out or the loop wakes up and checks ContinueRun(). In the past I've had a $Asleep variable and check it when coming into the while loop. If it is true, I sleep 20 more seconds; if it is false, I run the real code and then set it to true. I do this until I've slept X amount (defined by the user).

The problem I am now having is that I want the NT Service to be a SOAP server (using SOAP::Lite). If you recall, to start a SOAP::Lite daemon listening you run $daemon->handle(). This gives control to the SOAP::Lite module. Oops! How can I check the ContinueRun() function that let's me listen for NT telling me to stop? Is there a way (aside from modifying SOAP::Lite) to check ConitnueRun()? I've considered using POE and making the code ACT threaded, but that seems like a big undertaking just to check a function.

Your thoughts are GREATLY appreciated,
Casey

Replies are listed 'Best First'.
Re: SOAP in an NT Service
by $code or die (Deacon) on Jan 26, 2002 at 03:39 UTC

    I had to do something similar once. I experimented with fork but it wasn't too stable. In the end, I used Win32::Process in the NT Service to create the child process (in this case the SOAP server.) Then the service was essentially just the Loop, and if a STOP command was issued, the service killed the child process. You'll probably want to give the SOAP server some kind of signal to shut down safely. Think also about preventing the child process from lingering after the service has stopped.

    ___ Simon Flack ($code or die)
    $,=reverse'"ro_';s,$,\$,;s,$,lc ref sub{},e;$,
    =~y'_"' ';eval"die";print $_,lc substr$@,0,3;
      That's a great idea! I am not normally a Win32 coder (but seem to be asked to write a lot lately).

      I perused the Win32::Process documentation. It looks like I can use the Win32::Process::KillProcess($pid, $exitcode) to stop the process before exiting. The more I think about it, this works great. I actually have two SOAP servers, so I can run them both underneath one NT Service.

      The best part is, I plan to make the project support both Win32 and Unix/Linux. Now, the only difference in the project will be the daemon piece (NT Service on Win32 and daemon on UNIX/Linux). Stop the Service/daemon and both SOAP servers stop.

      Brilliance!

      Thank you!
      Casey