Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Status of long running module call

by dayton (Acolyte)
on Jul 05, 2017 at 13:10 UTC ( [id://1194240]=perlquestion: print w/replies, xml ) Need Help??

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

I'm using the Amazon::S3 module and trying to list the contents ("keys") of the buckets I have access to. Most of the buckets return quickly, but there are a few that have a lot of entries and take longer. I'd like to be able to issue the call to S3 and, display some kind of status if it takes longer than x seconds to return...
$s3 = Amazon::S3->new({aws_access_key_id=> $access_id,aws_secret_ +access_key => $secret_key,retry=> 1}); $bucket = $s3->bucket($b) or die $s3->err . ": " . $s3->errstr; $response = $bucket->list_all or die $s3->err . ": " . $s3->errst +r; if (@{ $response->{keys} }) { # show the contents }
Is there a way to start "$bucket->list_all" and then do "something else" while waiting for it to return? I've tried various permutations of if/while loops, using "eval {$response..}" but haven't been able to hit on the correct way. Ideally, I'd prefer not installing another module (trying to keep it light) but can if needed. Would fork() be the way to go? I know the topic of spinners/status bars has been brought up many times, and I generally know how to do that - I just can't figure out who to loop around this call to a module...

Replies are listed 'Best First'.
Re: Status of long running module call
by kennethk (Abbot) on Jul 05, 2017 at 14:59 UTC
    There are a number of different ways to attack this challenge: threads, pipe/fork with alarm, several worker pool modules... If you are trying to stick with CORE install, what version of perl are you running? Be aware that alarm would only work if you are running one query at a time, because otherwise the alarms may interfere.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Status of long running module call
by 1nickt (Canon) on Jul 05, 2017 at 14:53 UTC

    Where do you want to display the status? If you have a web UI you would be better off using the display layer to show a progress bar or similar: there are tons of ways to do that using Ajax requests, for example.

    If you want to display the progress in a terminal in which you're running the program, you could simply print the name of each bucket as you initiate the fetch, or you could look at a module such as Term::ProgressBar.

    Or you could use some form of IPC, for example a MCE::Shared variable and a forked process, as you mentioned.

    But it's unclear to me not only where you want to display the progress, but also why you would need to. You may want to change your storage design if you find that you do. If your bucket has many keys, it's going to take a while to fetch them all, especially since list_all() likely involves multiple S3 requests. If you need to iterate through your keys on a regular basis, consider implementing an index of some kind, e.g. a key that holds a list of other key names.

    Hope this helps!


    The way forward always starts with a minimal test.
      Thanks for the reply... It's a terminal, and I'm fine with actually displaying the results once the bucket is listed... what I'm struggling with is just some kind of status (a spinner or messages like "still working", please wait) while the Amazon::S3 call is being processed.. I have a few spinner routines I've used before, but I just can't get them to work in this case something like
      $bucket = $s3->bucket($b) or die $s3->err . ": " . $s3->errstr; print "\nGetting contents of S3 bucket: [$b] \n\tThis might take a + while...\n\n"; while ( ! @{ $response->{keys} } ){ $response = $bucket->list_all or die $s3->err . ": " . $s3->er +rstr; #please wait status } # display bucket contents
      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Status of long running module call
by Marshall (Canon) on Jul 06, 2017 at 19:04 UTC
    This is an advice post, not a code post.

    I have worked on CLI based field service software tools before. The UI for such things can be problematic. For what its worth, I'll make a few comments from my experience and resulting "scar tissue". For one project I was assigned the job of UI czar for 70 utilities. Learned a lot by talking with users about what was wrong. I had to "fix" the UI's of a bunch of programs that had already been written - this was hard to do. But I learned some stuff.

    Some important factors are: who your users are, how much experience they have running your program and what their expectations are for "timeliness" of the results. We had some situations where the tech's would come to believe that the program was "stuck" and they would abend it in some aggressive fashion (like CTRL-C). For a variety of reasons this "premature program abortion" often made the service problem worse!

    One of these things that we found out was that this simple "spinner" type gizmo doesn't work very well. The users quickly came to realize that this "spinner" thing or Windows "hour glass of death" idea was a separate process that just kept their eyes busy, but had no relationship as to whether actual work was being done or not. It looks cool, but didn't affect the user's decision to abend the program much if at all.

    One effective way to present "work is still happening" via CLI is to just print a "." every so many "work units". Tweak the number of "work units" each dot represents. If the dots come at irregular time intervals, so much the better. This re-enforces the user perception that something "real" is happening underneath the covers. The user is less likely to abend the program. Again a simple "spinner" is not as effective - users know that "spinners" are usually "nonsense".

    Best is of course if you can predict in advance say "how many work units" are needed and then present progress in percent towards that goal. If the "progress bar" moves every 30 seconds or so, that is enough. However a fancy progress bar is not needed, all that is needed is to present some status that clearly indicates "I am not hung, I just did X more records". The users will be patient if they are convinced that the program is actually doing something.

    In your Amazon application, is it possible to give the user some metric about the size of the request? The users will via experience learn how long a "level 10" request vs a "level 1000" takes. If "level 10", ok wait for it right away, "level 10,000", let's go to lunch. For frequent users familiar with the program this approach can work very well even if you can't provide an on-going update about progress of the current request. I think this might have application in your situation?

    I don't know if in this case whether it is possible or not, but consider breaking down complex requests (if at all possible) so that something happens for the user every say 20 seconds. By that I mean some kind of increment of user data is obtained, not just print a dot.

    The users will trust the U/I if it "doesn't lie". Don't say "might take a long time" if you don't think that it will. An experienced user will allow at least 10-15 seconds for a command. Once a command runs for 60-90 seconds without apparent results, even an experienced user can come to doubt that something is happening. And again, just because some hour glass thing is there, that makes little difference in the determination that "program is hung".

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1194240]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2024-04-19 11:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found