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

I have a Perl CGI script that runs on Apache on Linux using mod_cgi. The script takes a XML document POSTed by the client, parses it, validates the data, places the order into the Oracle database, sends a response back to the customer, then creates a log entry of what happened. Unfortnately I have one customer who insists on not waiting for an acknowlegment (even tho he requests one) but drops the connection as soon as the data is on the wire. This (I think) is causing Apache to terminate the CGI process before it completes the processing. Sometimes the order gets placed, sometimes it does not. Since logging happens at the end, I don't always know an order was attempted.

Is there any way I can capture this early terminaition so I can handle it intelligently? I know how to set up a signal handler but I don't know what signal -- if any -- to look for.

Replies are listed 'Best First'.
Re: Detecting early termination by client
by Joost (Canon) on Apr 16, 2005 at 18:30 UTC
    I'm pretty sure you should check for a $SIG{PIPE}, but that signal will only be raised if you try to send data over a closed connection i.e. print to STDOUT under mod_cgi.

    I'm not at all sure how this will interact with buffering; even if you've turned buffering off (set $|=1), apache might cache the script output before attempting to send it to the client. Maybe someone else here can fill you in on the details, otherwise, you'll have to experiment.

      Thank you. That will give me a place to start. I have identified the particular customer number so I can add some special handling without affecting other customers.
Re: Detecting early termination by client
by Mabooka-Mabooka (Sexton) on Apr 17, 2005 at 05:04 UTC
    Would be lovely to know more. So, this customer doesn't want an acknowledgement, but insists on one? An acknowledgement of.. what?
    I speculate that there're two possible acknowledgments here:
    1) "I received your XML";
    2) "I successfully process-etc-ed it".

    If that is so, de-coupling the code into to parts:
    1) getting the client data;l
    2) processing it asynchronously

    would do?
    (you'll probabaly still have to add
    if($customer is not in $my_piss_off_list) { only_notify_once...}
    ., but that'ok?
      > Would be lovely to know more. So, this customer doesn't want
      > an acknowledgement, but insists on one?

      Yup. The CGI is part of a system that provides Flood Certificates to Loan companies and Banks. If the Boolean "WaitForCertificate" is set "T" then the customer is indicating he wants a finished certificate sent on the open channel. There is also a provision for the XML copy of the certifcation to be set back to a ResponseURL. The PDF only can be sent via Email or FAX. A customer can even indicate don't send him anything. Presumably he'll send a query when he's ready for it.

      > An acknowledgement of.. what?

      An XML document which is either a compelte certificate or tells him where the order went and trackng information.

      > I speculate that there're two possible acknowledgments here:
      > 1) "I received your XML";
      > 2) "I successfully process-etc-ed it".

      Essentially yes tho number 2 can be a pretty wide range of responses.

      > If that is so, de-coupling the code into to parts:
      > 1) getting the client data;l
      > 2) processing it asynchronously

      I doubt seriously if other customers would tolerate this. Most want an answer back three seconds before they send it but are willing to tolerate a plus five to plus ten second delay. It may become necesary to just change the settings for this one customer from wahtehe says he wants to what his behavior indicates he really wants. I hate that kind of second guessing tho.

        Banks, sertificates, faxes,,, -yuck!

        So, again; what's wrong if you:
        1) suck the data out; 2) put it somewhere so the ProcessDataDaemon will pick it up; 3) in the meantime, display a page: "Thank you for submitting blah... +Press here to view your valuable blah-blah..." , or "Check your email soon to view few-few..." - ?
Re: Detecting early termination by client
by bibliophile (Prior) on Apr 18, 2005 at 16:42 UTC
    I'd have the system automagically send back an email saying "I'm sorry, the transaction was aborted at your request" every time the user drops the connection... in the hope that eventually they'd learn :-)

    Perhaps log a "starting transaction" and "transaction complete" at either end of the process, and then periodically scan the log for started-but-not-completed...?

    Update: changed subject back to something relevent.

      That is what I would like to do and I think should be the default behavior. After all if someone hits the close or stop button it's a good bet he wants the transaction halted. Unfortunately the boss does not agree.

      As a temporary measure I have taken to creating "emergency" logs for each transaction this particuar customer attempts. I spent today wrestling with SSL cetificate and Oracle AS 10g. Hopefully tomorrow I can load up teh CGI code and start experimenting.