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

I have been working on a command line script that makes several system calls, some of which take a few seconds (minutes?) to return. The long pauses give the impression that the script has hung, which isn't great. I figured I could address this by adding some kind of visual "still processing" feedback, like an hourglass or pinwheel. Because it's just a command line script, I do it with dots.
My code is below. I would appreciate any feedback or suggestions for improvement. Thank you.

use strict; use threads; use threads::shared; sub SystemCall { my $call = join ' ', @_; local $| = 1; # run hot pipes print "Executing system call '$call'"; # Start a thread to print out dots indicating that Perl hasn't hun +g my $thread_beat = 0.1; # Should be small, but not so small as to f +lood the screen with dots. my $stop :shared = 0; my $thread = threads->create( {'context' => 'void'}, sub { while ( not $stop ) { print '.'; select( undef,undef,undef, $t +hread_beat ) } }); $thread->detach(); # Run the command my $result; eval { chomp( $result = `$call` ) }; warn $@ if $@; # eval failed. # Signal the thread to end. $stop = 1; # And wait one beat for the thread to end. select( undef,undef,undef, $thread_beat + 0.01 ); print $/; # Present error message status, if any. warn "\$? = '$?'\n" if defined $? and $?; warn "\$! = '$!'\n" if defined $! and $!; warn "\$@ = '$@'\n" if defined $@ and $@; warn "\$^E = '$^E'\n" if defined $^E and $^E; warn "\$^W = '$^W'\n" if defined $^W and $^W; if ( $result ) { print $result, $/ } return defined $result ? $result : ''; }

Replies are listed 'Best First'.
Re: Using a thread to provide visual feedback.
by BrowserUk (Patriarch) on Jun 21, 2018 at 20:03 UTC

    Try something like this:

    #! perl -slw use strict; use threads; use threads::shared; sub nap { select '','','', $_[0] } my $done:shared = 0; my $thread = async( sub { $|++; until( $done ) { nap( 0.1 ), printf "\r%s\t\t", '.' x $_ for 1 .. 10, reverse +1 .. 10; nap( 0.01 ), printf "\r%s\t\t", '.' x $_ for 1 .. 10, reverse +1 .. 10; nap( 0.8 ); } }, $done ); sleep 60; $done = 1; $thread->join;

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

      For folks using Perl not built to support threads and wanting to try BrowserUk's example, here is the same thing using MCE::Hobo and MCE::Shared.

      #! perl -slw use strict; use MCE::Hobo; use MCE::Shared; sub nap { select '','','', $_[0] } tie my $done, 'MCE::Shared', 0; my $hobo = mce_async( sub { $|++; until( $done ) { nap( 0.1 ), printf "\r%s\t\t", '.' x $_ for 1 .. 10, reverse +1 .. 10; nap( 0.01 ), printf "\r%s\t\t", '.' x $_ for 1 .. 10, reverse +1 .. 10; nap( 0.8 ); } }, $done ); sleep 10; $done = 1; $hobo->join;

      This, right here, is why I think BrowserUk magically finds threads like this.

Re: Using a thread to provide visual feedback.
by bliako (Abbot) on Jun 21, 2018 at 16:49 UTC
      I saw those, but I didn't see how to use them without blocking the system call. The entire point here was to give visual "I'm alive" feedback to a person running a command line script. The use of dots isn't the interesting part, it's the use of threads that's interesting. Does the Animation module support that?

        I hope that's enough of visual feedback and non-blocking too.

        bw, bliako

        ps. using asciiquarium by Kirk Baucom (aythor of Term::Animation) and Joan Stark

        Edit: changed the program a bit so as to stop without resorting to signal but by passing a ref to the shared variable $stop.

Re: Using a thread to provide visual feedback.
by Anonymous Monk on Jun 21, 2018 at 16:38 UTC
    On a web site, for example, an animated GIF works beautifully.