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

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

Hi

I want to write a perl script that will run as a Win32 service and respond to SOAP / XMLRPC calls.

Win32::Daemon requires that you have your code in a loop that does processing, then checks the service state for any callbacks / messages..

SOAP::Lite (And XMLRPC::Lite) servers generally expect you to create a server instance and pass control to it..

What is the best way to go about doing this? Can I make my SOAP::Lite server return after each call and / or a timeout so that I can do other processing, or am I going to have to do something horrid like forking and having one process to manage the service and one being the SOAP server (with their IPC in SOAP I assume)..

Thanks in advance for the help.

Replies are listed 'Best First'.
Re: SOAP::Lite and Win32::Daemon
by one4k4 (Hermit) on Feb 04, 2004 at 15:47 UTC
    I'm currently working on similar code.. Instead of using Win32::Daemon, I just have a script that runs in a while loop. It's not the cleanest thing in the world, but I can have a "daemon" running and processing messages as necessary. I know that SOAP::Lite can be run as a daemon..
    my $daemon = SOAP::Transport::HTTP::Daemon -> new (LocalAddr => '207.000.000.000', LocalPort => 80) -> dispatch_to('_Whatever')
    That processes under sigint properly. It's what I'm using. The package it dispatches to is internal. All it has is two subroutines. One for stuffing messages into a table. One for picking them out of an outgoing messages table. The "deamon" mentioned above does the work of running under the while loop and grabbing the messages out of the db. It's not much, but it's just my two cents. I hope I could offer at least a view of what somebody else is trying out.
      The problem with that is that I need this script to start at boot time and run without user intervention / ability for user to kill it off..
        If you're running at least Windows 2000 Server, just go into scheduled tasks, and create one for this process. Set its run time to "At system startup" and don't allow it to interact with the console. Users won't see it unless they look at the process list, and it will run even when no one is logged in. That's how we run our Wiki script. Much easier than a service wrapper if you just need to get it running quickly.

        Of course a service is the right way to go if you want remote start/stop and stuff.

        --
        Spring: Forces, Coiled Again!
Re: SOAP::Lite and Win32::Daemon
by dbush (Deacon) on Feb 04, 2004 at 16:39 UTC

    Hi bobtfish,

    I had a similar situation and used the solution outlined in this thread.

    Update:
    Forgot to mention that I have no communication between the two parts. If the service is stopped it simply kills the SOAP process. As you say in your original message, it would be better for the service to request the SOAP server to exit.

    Regards,
    Dom.

      Cheers, that's exactly what I was looking for..
Re: SOAP::Lite and Win32::Daemon
by bsdz (Friar) on Feb 04, 2004 at 15:56 UTC

    You may consider Activestate's perlapp or perlsvc command. I've been successful using perlapp and compiling a SOAP::Lite application as a gui and running it in user context(at startup). I.e.

    use SOAP::Transport::HTTP;
    use MyMod;
    $daemon = SOAP::Transport::HTTP::Daemon
    -> new (LocalPort => 6000, ReuseAddr => 1)
    -> dispatch_to('MyMod')
    ;
    $daemon->handle;
    

    I'm not sure how this works using Win32::Daemon (I've had problems with this package before as it can be confusing how to apply it correctly)

    If you're using Win32 ithreads you may want to set Win32::SetChildShowWindow(0) in each thread when calling system or backticks.

    I would keep clear of RPC::PlServer which is not memory friendly (probably due to Net::Daemon and ithreads!)

Re: SOAP::Lite and Win32::Daemon
by NetWallah (Canon) on Feb 04, 2004 at 20:57 UTC
    Here is a thought - I know you would resist a forked solution, but it seems to solve the issues in this problem domain. How about the main service (Process A) loop Fork off a process that handles the XML-HTTP/Soap etc (Process B).

    Now, Process A can also be a client of Process B.
    When we receive a Service termination request in Process A, we simply turn around and do a SOAP call to process B, asking it to please terminate. Then Process A terminates, and everyone dies happily.

    (I dislike the idea of a cruel Infanticide, particularly when the victim is completely clueless why it is being killed.)

    "When you are faced with a dilemma, might as well make dilemmanade. "