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

relevant code
my $outfile = "> /home/vobadmin/scripts/CC_mass_protect_element_log.tx +t"; open (OUTFILE,$outfile); timestamp(); # #### Get list of components from specific vob # my @voblist = `cat /home/vobadmin/scripts/voblist.txt`; foreach my $i (@voblist) { chomp($i); my $vob = "\/vobs\/$i"; chomp($vob); print '[' . timestamp() . '] Start Time'. "\n"; print OUTFILE '[' . timestamp() . '] Start Time'. "\n"; print "VOB is: $vob\n"; chdir $vob; print "Loading Array with all elements from vob: $vob\n"; my @element = `cleartool find \. \-all \-print`; my @complist = `ls $vob`; foreach my $comp (@complist) { chomp ($comp); if ($comp ne "lost\+found") { my $comppath = "$vob\/$comp"; chomp($comppath); print OUTFILE "COMPONENT IS: $comppath\n"; my $group = `cleartool desc -fmt \"%[group]p\" $comppath`; print "Getting Group for Comp: $group\n"; #print "Change Directory to Comp: $comppath\n"; #chdir $comppath; my @matches = grep {/$comppath/} @element; $comp_counter = 0; foreach my $elem (@matches) { chomp($elem); #print " Execute: $elem\n"; print "Running Command \`cleartool protect -chown vobad +min -chgrp $group -chmod 775 $elem\`\n"; my $result = `cleartool protect \-chown vobadmin \-chgr +p $group \-chmod 775 \"$elem\"`; print "\|\-\-\-\-\> $result\n"; $comp_counter++; } print OUTFILE "-----Total Elements for $comppath is: $comp +_counter\n"; } else { print "$comp is not component skipping\n"; next; } print '[' . timestamp() . ']: End Time'. "\n"; print OUTFILE '[' . timestamp() . '] End Time'. "\n"; } } sub timestamp { return localtime (time); } close OUTFILE;

During this moment my @element = `cleartool find \. \-all \-print`; which takes up to 25 minutes to gather all the elements I want to be able to show a progress or alive status on screen (dots, spinning pipe, etc..) to let user know the script is actually running.

Replies are listed 'Best First'.
Re: marking time during function call
by kcott (Archbishop) on Jun 17, 2015 at 03:06 UTC

    G'day lycanhunter,

    Welcome to the Monastery.

    Without seeing any code or even knowing how your application is to be run, here's some module suggestions.

    Smart::Comments
    Possibly the easiest to use. See both the Progress Bars and Time-Remaining Estimates sections. It uses source filters which could be a potential problem: see BUGS AND LIMITATIONS.
    Term::Spinner
    This displays a text-based spinner. It shows that the program is still running but doesn't give any indication of progress. This module requires Moose.
    Tk::ProgressBar
    If your application is a Tk GUI, this provides a graphical progress bar. Other GUIs will typically provide their own graphical progress bars.

    If you provide better initial information, we can provide better help. I appreciate this is your first post and possibly you weren't aware what sort of details we needed. Before posting again, please read "How do I post a question effectively?": better questions get better answers.

    -- Ken

Re: marking time during function call
by Laurent_R (Canon) on Jun 16, 2015 at 21:34 UTC
    Loading an array for up to 25 minutes and not running out of memory? That sounds uncommon. Unless, of course, loading the array really means a lot of computation work. But, then, perhaps you should say more about this process.

    Maybe simply counting the elements added to the array and printing out some message each time that number is a multiple of some predetermined value (say, for example, 10,000). We are doing that all the time in a slightly different context: extracting data from a database for hours and hours (sometimes even days), and printing into the log file the date and the number of records extracted every 10,000 (or whatever) records. This way we can know at any point that the task is progressing, that it is not just hanging doing nothing.

Re: marking time during function call
by stevieb (Canon) on Jun 16, 2015 at 20:41 UTC

    This can be done by offloading the work that takes a long time to a separate script, and calling that one from a primary script.

    The first file (call.pl) calls via a background system() call to the script that does the actual work that takes a long time (busy.pl). While busy.pl is doing stuff, the call.pl loops over to check for a lock file, and will inform the user that work is going on in the background.

    In the busy.pl file, replace sleep() with the code that takes a long time, and edit call.pl to your liking so it notifies however often you want it to.

    call.pl

    #!/usr/bin/perl # call.pl use warnings; use strict; my $lock_file = 'lock.lck'; print "$0: Calling subtask script...\n"; system("/usr/bin/perl busy.pl &"); my $start = 0; while(1){ # on first loop, sleep two seconds before checking # for the lock file sleep(2) if ! $start; $start++; if (-e $lock_file){ print "$0: Subtask still running...\n"; sleep(1); next; } print "$0: Done!\n"; exit; }

    busy.pl

    #!/usr/bin/perl # busy.pl use warnings; use strict; my $lock_file = 'lock.lck'; open my $lock, '>', $lock_file or die "Can't grab a lock file: $!"; print "$0: Starting subtask...\n"; sleep(5); print "$0: Ending subtask...\n"; close $lock; unlink $lock_file;

    Output:

    $ perl call.pl call.pl: Calling subtask script... busy.pl: Starting subtask... call.pl: Subtask still running... call.pl: Subtask still running... call.pl: Subtask still running... call.pl: Subtask still running... busy.pl: Ending subtask... call.pl: Done!

    -stevieb

Re: marking time during function call
by neilwatson (Priest) on Jun 16, 2015 at 17:50 UTC

    What type of operation requires 25 minutes? And if that can't be improved then the load should be automated and the data cached locally so that the user can treat it as the original without delay.

    Neil Watson
    watson-wilson.ca

Re: marking time during function call
by afoken (Chancellor) on Jun 17, 2015 at 07:28 UTC

    As usual: Show some relevant code. Everything else forces us to guess.

    To find hot spots in your code, use Devel::NYTProf:

    perl -dNYTProf yourscript.pl nytprofhtml --open

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: marking time during function call
by Hosen1989 (Scribe) on Jun 16, 2015 at 19:08 UTC

    Hi,

    Can you at lest give us sample of your code so we can help you

Re: marking time during function call
by QM (Parson) on Jun 17, 2015 at 10:30 UTC
    If the load is multiple statements, you can easily put in a ticker, either by number of steps, or by time lapsed.

    In some cases you may be able to interrupt whatever is happening with an alarm to print a ticker, set another alarm, and the resume the activity. This is highly dependent on what is actually running. With safe signals, some actions are not nicely interruptible.

    Show some toy code, and someone will be along to tweak it for you.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

      the script now works with a heartbeat. Thank You again

      my @voblist = `cat /home/vobadmin/scripts/voblist.txt`; foreach my $i (@voblist) { chomp($i); my $vob = "\/vobs\/$i"; chomp($vob); print '[' . timestamp() . '] Start Time'. "\n"; print OUTFILE '[' . timestamp() . '] Start Time'. "\n"; print "VOB is: $vob\n"; chdir $vob; open($FH, "cleartool find . -all -print|") or die "Something went wrong\n"; print STDERR "Loading Array with elements from $vob\n "; while (<$FH>) { push @element, $_; unless ($. % 10) { # every 10 lines print STDERR "."; } } print "\n";

      Now fill the array while it is keeping heartbeat.

      A simple script would be like

      @march = `cleartool find /vobs/41Rational_Val/. -all -print`; while (<@march>) { ### processing... done } print "\n"; close(@march);

      This using the Smart Comments module. But it waits until the load of the array finishes before displaying the progress.

        I don't have time at the moment to do full justice to this, but an (untested!) snippet might look like this:
        open(my $FH, "cleartool find /vobs/41Rational_Val/. -all -print|") or die "Something went wrong\n"; print STDERR "Reading cleartool command, line "; while (<$FH>) { do_something_here; unless ($. % 200) { # every 200 lines print STDERR "$. "; } }

        However, there is no way to know the percent complete progress of the cleartool command.

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of