Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Keep running script but ending it to the browser

by cowgirl (Acolyte)
on Aug 07, 2008 at 16:05 UTC ( [id://702914]=perlquestion: print w/replies, xml ) Need Help??

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

I have a temporary image file that is generated by a script It then is loaded by the browser in the output of the script (e.g. <img src="temp_Ad934C.gif">). However, it needs to be deleted after it is shown. I could do this by replacing the filename of the image by a script that deletes the file after it is run (e.g. <img src="">) but this is too sensitive for hazardous attacks. I tried to use an END block that is executed after the main script is executed and it deletes the tempfile after 5 seconds. However when running this, the browser first waits 5 seconds before displaying the page. This is obvious as the script is still running. How can I force Perl to end the connection with the browser but keep running the script?
END { #delay delete tempfile my $oldtime = (time + 5); my $i=1; while ($i==1) { if (time > $oldtime) { $i=0; if($tempfile ne "") { unlink($tempfile) } } } }

Replies are listed 'Best First'.
Re: Keep running script but ending it to the browser
by JavaFan (Canon) on Aug 07, 2008 at 16:17 UTC
    One way of doing so it to put the image generating part of the script in a different script, and put the URL of the different script in the value of the SRC attribute. You may need to give it arguments if that's needed to generate the image. So you get something like:
    <img src = "make_image?parameters">
    where make_image generates the image. That image can then be written to STDOUT and doesn't have to reside on the disk at all.
      I am now using this:
      END { system "nohup sleep 15 ; echo test >/dev/null 2>&1 &"; }
      However inside the shell if the script is executed, it ends succesfully but then waits for 15 seconds before returning to the shell. Inside the browser the same thing happens, exactly 15 seconds after requesting the page, the page is returned. To see the problem I have added a time counter and the runtime is only around 0.2 seconds but it takes 15.2 in reality. Am I implementing the code wrong?
        Your first approach didn't look that bad (okay, I would suggest a sleep 5; instead of busy-waiting / saves some CPU). Anyway, the browser keeps waiting because it waits for further HTTP data on a still open TCP connection. If you can manage to close the connection before waiting to remove the file, shouldn't that fix the problem?
        Another Idea: Unless the temporary GIFs must be removed immediately, why not let them live for a while until the next invocation of your program? At the end of your program use stat() to remove all of your GIFs from previous runs whose ctime is older than than the maximum lifespan. Alternatively, you can run a small daemon to keep the directory clean. Should work for low traffic scenarios.
      Yes that was my idea but the problem is that the script is run from the browser. It then needs to generate the image from data sent by the browser and return a HTML page with with the image tag in there. Ofcourse I could use the data sent by the browser and use it to execute the image script but I would like to minimze data sent as much as possible (it's for a mobile app). I would rather just have the image be generated to a fileand then displaying it by way of its filename and then deleting it again.
        Why would using 2 scripts transfer more data? You will still have the client do two requests, and you still have both the HTML and the image data send to the client.
        This is what sessions are for. Just create a session upon the first request, storing all data needed for image generation. The first request gives back the HTML page that contains an img tag pointing to the script that generates the image; at this point you only need to provide it the session id and you're done: one data transfer, two scripts, no temporary files.

        perl -ple'$_=reverse' <<<ti.xittelop@oivalf

        Io ho capito... ma tu che hai detto?
Re: Keep running script but ending it to the browser
by BrowserUk (Patriarch) on Aug 07, 2008 at 16:19 UTC
Re: Keep running script but ending it to the browser
by Bloodnok (Vicar) on Aug 07, 2008 at 16:19 UTC
    Why not use the CB suggestion, which if I understood it correctly, would be along the lines of (assuming *NIX-like OS)...
    END { system "at now + 5 secs 'rm $tempfile'"; }
    In this way, your perl script has handed over responsibility for the file deletion to the underlying OS immediately before ending - hence the connection to the browser will be dropped straight away.

    Again assuming *NIX OS, man at should clear up any syntactical probs contained within my suggestion.

    HTH ,

    A user level that continues to overstate my experience :-))
      Not on my system, and probably not on many other systems either. The UID the webserver is running is in /etc/at.deny (and /etc/cron.deny) and hence CGI programs will not be able to do remote-time execution.
        Never thought of that JavaFan.

        OK, how's about...

        END { system "nohup sleep 5 ; rm $tempfile >/dev/null 2>&1 &"; }
        or similar ...

        A user level that continues to overstate my experience :-))
Re: Keep running script but ending it to the browser
by hangon (Deacon) on Aug 07, 2008 at 18:32 UTC

    Why not fork a separate process from your script to handle it? Something like this (untested):

    END { my $pid; if ($pid = fork){ exit; }elsif (defined $pid){ close STDOUT; sleep 5; unlink ($tempfile); }else{ # if fork fails: sleep 5; unlink ($tempfile); } }
Re: Keep running script but ending it to the browser
by Anonymous Monk on Aug 07, 2008 at 16:20 UTC

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://702914]
Approved by toolic
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-06-23 10:40 GMT
Find Nodes?
    Voting Booth?

    No recent polls found

    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.