You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Arshavir Grigorian <ag...@m-cam.com> on 2005/05/23 21:21:11 UTC

progress reporting

Hi,

I have some code that takes a long time to execute. What I would like to 
do is to display several real time status messages on the user's browser 
as the work is being done (Started doing A ... Done, Started doing B ... 
Done, etc). Then once the work is done, I would like to wipe the status 
messages and display some results.

I am thinking that I need is something similar to internal redirects, 
but I am not sure what. Thanks for any ideas/pointers.


-- 
Arshavir Grigorian
Systems Administrator/Engineer

Re: progress reporting

Posted by "Philip M. Gollucci" <pg...@p6m7g8.com>.
Arshavir Grigorian wrote:

> Hi,
>
> I have some code that takes a long time to execute. What I would like 
> to do is to display several real time status messages on the user's 
> browser as the work is being done (Started doing A ... Done, Started 
> doing B ... Done, etc). Then once the work is done, I would like to 
> wipe the status messages and display some results.
>
> I am thinking that I need is something similar to internal redirects, 
> but I am not sure what. Thanks for any ideas/pointers.
>
>
You might try something similiar to webmin with nph scripts we use nph 
and local $| in house to do this.

also try using

local $| = 1

HANDLE->autoflush(EXPR)
$OUTPUT_AUTOFLUSH
       $|      If set to nonzero, forces a flush right away and after every
               write or print on the currently selected output channel.
               Default is 0 (regardless of whether the channel is really
               buffered by the system or not; $| tells you only whether 
you've
               asked Perl explicitly to flush after each write).  STDOUT 
will
               typically be line buffered if output is to the terminal and
               block buffered otherwise.  Setting this variable is 
useful pri-
               marily when you are outputting to a pipe or socket, such as
               when you are running a Perl program under rsh and want to see
               the output as it's happening.  This has no effect on input
               buffering.  See "getc" in perlfunc for that.  (Mnemonic: when
               you want your pipes to be piping hot.)


-- 
END 
---------------------------------------------------------
    What doesn't kill us, can only make us stronger.
               Nothing is impossible.
				
Philip M. Gollucci (pgollucci@p6m7g8.com) 301.254.5198
Consultant / http://p6m7g8.net/Resume/resume.shtml
Senior Developer / Liquidity Services, Inc.  
     http://www.liquidityservicesinc.com


Re: progress reporting

Posted by Torsten Foertsch <to...@gmx.net>.
On Tuesday 14 June 2005 21:21, Arshavir Grigorian wrote:
> >>I have some code that takes a long time to execute. What I would like to
> >>do is to display several real time status messages on the user's browser
> >>as the work is being done (Started doing A ... Done, Started doing B ...
> >>Done, etc). Then once the work is done, I would like to wipe the status
> >>messages and display some results.

You can try to set the connection's keepalive status to close, send the 
initial status with a Refresh-header and register a cleanup handler either 
for the request or the connection. (I'd prefer the connection) That cleanup 
handler is then the place to do your long-time computing.

See Apache2::Connection::keepalive, Apache2::Request::connection, 
Apache2::Request::pool or Apache2::Connection::pool, 
Apache2::Pool::cleanup_register.

Torsten

Re: progress reporting

Posted by Perrin Harkins <pe...@elem.com>.
On Tue, 2005-06-14 at 15:44 -0400, Arshavir Grigorian wrote:
> Thanks. I tried doing the following, but it didn't seem to help. I 
> wonder if it has to do with using Apache::DBI.

It does.  This is my least favorite thing about Apache::DBI -- it
overrides disconnect.

> $r->pnotes('dbh')->disconnect();

Try this:
$r->pnotes('dbh')->DBI::db::disconnect();

- Perrin


Re: progress reporting

Posted by Arshavir Grigorian <ag...@m-cam.com>.
David Dick wrote:
> Looks suspiciously like you are forking with an open database 
> connection.  Perhaps you should try closing the database connection 
> before the fork and opening it directly after the fork.
> 
> However, this of course means that you need to sort out any pending 
> commits/rollbacks.
> 
> Uru
> -Dave

Thanks. I tried doing the following, but it didn't seem to help. I 
wonder if it has to do with using Apache::DBI.

+ $r->pnotes('dbh')->disconnect();

defined(my $childpid = fork()) or die "Cannot fork: $!";

if ($childpid) {

     sleep 5;

     $r->headers_out->set(Location => '/status/');

     return Apache2::Const::REDIRECT;

} else {

     open STDIN, "</dev/null";
     open STDOUT, ">/dev/null";


     + $r->pnotes( 'dbh' => Utils->connect() );

     my $object = Class->new();
     $object->generate_resultset();

     return Apache2::Const::OK;
}

> 
> Arshavir Grigorian wrote:
> 
>> Perrin Harkins wrote:
>>
>>> On Monday 23 May 2005 3:21 pm, Arshavir Grigorian wrote:
>>>
>>>> I have some code that takes a long time to execute. What I would 
>>>> like to
>>>> do is to display several real time status messages on the user's 
>>>> browser
>>>> as the work is being done (Started doing A ... Done, Started doing B 
>>>> ...
>>>> Done, etc). Then once the work is done, I would like to wipe the status
>>>> messages and display some results.
>>>
>>>
>>>
>>>
>>> See Randal's columns on this subject:
>>> http://www.stonehenge.com/merlyn/LinuxMag/col39.html
>>> http://www.stonehenge.com/merlyn/WebTechniques/col20.html
>>>
>>> - Perrin
>>
>>
>>
>> Following Randal's examples, I wrote the following code which does not 
>> seem to work:
>>
>> defined(my $childpid = fork()) or die "Cannot fork: $!";
>>
>> if ($childpid) {
>>
>>    sleep 5;
>>
>>    $r->headers_out->set(Location => '/status/');
>>
>>    return Apache2::Const::REDIRECT;
>>
>> } else {
>>
>>     open STDIN, "</dev/null";
>>     open STDOUT, ">/dev/null";
>>
>>     my $object = Class->new();
>>     $object->generate_resultset();
>>
>>     return Apache2::Const::OK;
>> }
>>
>> [Tue Jun 14 14:23:24 2005] [error] Exception: DBD::Pg::st execute 
>> failed: lost synchronization with server: got message type " at 
>> Utils.pm line 38 - which is where I set the error handler on the 
>> DBI->connect().
>>
>> When I eliminate the fork() call, and do everything in a pipeline 
>> mode, everything works fine so I know the code works. However for some 
>> other tasks that I am going to code, which take much longer than this 
>> one, I would like to have the option of processing in the background.
>>
>> Thanks for any ideas.
>>
>>


-- 
Arshavir Grigorian
Systems Administrator/Engineer
M-CAM, Inc.
ag@m-cam.com
+1 703-682-0570 ext. 432
Contents Confidential

Re: progress reporting

Posted by David Dick <da...@iprimus.com.au>.
Looks suspiciously like you are forking with an open database 
connection.  Perhaps you should try closing the database connection 
before the fork and opening it directly after the fork.

However, this of course means that you need to sort out any pending 
commits/rollbacks.

Uru
-Dave

Arshavir Grigorian wrote:
> Perrin Harkins wrote:
> 
>> On Monday 23 May 2005 3:21 pm, Arshavir Grigorian wrote:
>>
>>> I have some code that takes a long time to execute. What I would like to
>>> do is to display several real time status messages on the user's browser
>>> as the work is being done (Started doing A ... Done, Started doing B ...
>>> Done, etc). Then once the work is done, I would like to wipe the status
>>> messages and display some results.
>>
>>
>>
>> See Randal's columns on this subject:
>> http://www.stonehenge.com/merlyn/LinuxMag/col39.html
>> http://www.stonehenge.com/merlyn/WebTechniques/col20.html
>>
>> - Perrin
> 
> 
> Following Randal's examples, I wrote the following code which does not 
> seem to work:
> 
> defined(my $childpid = fork()) or die "Cannot fork: $!";
> 
> if ($childpid) {
> 
>    sleep 5;
> 
>    $r->headers_out->set(Location => '/status/');
> 
>    return Apache2::Const::REDIRECT;
> 
> } else {
> 
>     open STDIN, "</dev/null";
>     open STDOUT, ">/dev/null";
> 
>     my $object = Class->new();
>     $object->generate_resultset();
> 
>     return Apache2::Const::OK;
> }
> 
> [Tue Jun 14 14:23:24 2005] [error] Exception: DBD::Pg::st execute 
> failed: lost synchronization with server: got message type " at Utils.pm 
> line 38 - which is where I set the error handler on the DBI->connect().
> 
> When I eliminate the fork() call, and do everything in a pipeline mode, 
> everything works fine so I know the code works. However for some other 
> tasks that I am going to code, which take much longer than this one, I 
> would like to have the option of processing in the background.
> 
> Thanks for any ideas.
> 
> 

Re: progress reporting

Posted by Arshavir Grigorian <ag...@m-cam.com>.
Perrin Harkins wrote:
> On Monday 23 May 2005 3:21 pm, Arshavir Grigorian wrote:
> 
>>I have some code that takes a long time to execute. What I would like to
>>do is to display several real time status messages on the user's browser
>>as the work is being done (Started doing A ... Done, Started doing B ...
>>Done, etc). Then once the work is done, I would like to wipe the status
>>messages and display some results.
> 
> 
> See Randal's columns on this subject:
> http://www.stonehenge.com/merlyn/LinuxMag/col39.html
> http://www.stonehenge.com/merlyn/WebTechniques/col20.html
> 
> - Perrin

Following Randal's examples, I wrote the following code which does not 
seem to work:

defined(my $childpid = fork()) or die "Cannot fork: $!"; 


if ($childpid) { 


    sleep 5; 


    $r->headers_out->set(Location => '/status/'); 


    return Apache2::Const::REDIRECT; 


} else { 


     open STDIN, "</dev/null"; 

     open STDOUT, ">/dev/null";

     my $object = Class->new();
     $object->generate_resultset();

     return Apache2::Const::OK;
}

[Tue Jun 14 14:23:24 2005] [error] Exception: DBD::Pg::st execute 
failed: lost synchronization with server: got message type " at Utils.pm 
line 38 - which is where I set the error handler on the DBI->connect().

When I eliminate the fork() call, and do everything in a pipeline mode, 
everything works fine so I know the code works. However for some other 
tasks that I am going to code, which take much longer than this one, I 
would like to have the option of processing in the background.

Thanks for any ideas.


-- 
Arshavir Grigorian
Systems Administrator/Engineer

Re: progress reporting

Posted by Perrin Harkins <pe...@elem.com>.
On Monday 23 May 2005 3:21 pm, Arshavir Grigorian wrote:
> I have some code that takes a long time to execute. What I would like to
> do is to display several real time status messages on the user's browser
> as the work is being done (Started doing A ... Done, Started doing B ...
> Done, etc). Then once the work is done, I would like to wipe the status
> messages and display some results.

See Randal's columns on this subject:
http://www.stonehenge.com/merlyn/LinuxMag/col39.html
http://www.stonehenge.com/merlyn/WebTechniques/col20.html

- Perrin