http://qs321.pair.com?node_id=11140473


in reply to making a loop script with a remote URL call faster

I'm with LanX, I don't really see how it would make sense to iterate the loop multiple times if price doesn't change, but if you really want a tight loop, everyone loves threads:

#!/usr/bin/perl -w use strict; use warnings; use threads; use threads::shared; my $PRICING :shared = 0; my $RUNNING :shared = 1; sub price_thread { while ($RUNNING) { # Local variable to limit lock time. # Catch errors in eval my $pricing = eval { # Net::Curl to remote URL... request here. my $val = 1000 * rand(); # [from net::curl] # ... more? # last line will go to $pricing and $pricing gets undef on + exception $val }; do { lock($PRICING); $PRICING = $pricing; }; # Optional pause between requests: sleep 60; } } sub main_loop { # Local variable to limit lock time and prevent changes mid-comput +ation my $pricing = 0; while ($RUNNING) { do { lock($PRICING); $pricing = $PRICING; }; # Optional - I don't know what you are doing with pricing, you + might want # to use 0 or undef to signal a request error (i.e., out-of-da +te data). next if !defined($pricing) or $pricing == 0; # Do something with $pricing; print "$pricing\n"; sleep 1; # Work simulation # return if QUIT CONDITION; } } my $thr = threads->create(\&price_thread); eval { main_loop() }; $RUNNING = 0; $thr->join();

Good Day,
    Dean

Replies are listed 'Best First'.
Re^2: making a loop script with a remote URL call faster
by marioroy (Prior) on Jul 08, 2022 at 02:05 UTC

    The following is duelafn's demonstration converted to using MCE::Hobo and MCE::Shared and runs in Perl lacking threads support. Locking is handled automatically behind the scene. I updated the code to run at each interval period.

    Update: Use monotonic clock.

    #!/usr/bin/perl -w use strict; use warnings; use MCE::Hobo; use MCE::Shared; use Time::HiRes qw(time sleep); # Use monotonic clock if available. use constant CLOCK_MONOTONIC => eval { Time::HiRes::clock_gettime( Time::HiRes::CLOCK_MONOTONIC() ); 1; }; sub _time { ( CLOCK_MONOTONIC ) ? Time::HiRes::clock_gettime( Time::HiRes::CLOCK_MONOTONIC() ) : Time::HiRes::time(); } my $DEBUG = 1; my $INTERVAL = $DEBUG ? 3.0 : 60.0; my $PRICING = MCE::Shared->scalar(0); my $RUNNING = MCE::Shared->scalar(1); sub price_thread { my $next_interval = _time() + $INTERVAL; while ($RUNNING->get()) { printf("# TIME %.3f\n", _time()) if $DEBUG; # Local variable to limit lock time. # Catch errors in eval my $pricing = eval { # Net::Curl to remote URL... request here. my $val = 1000 * rand(); # [from net::curl] # ... more? # last line will go to $pricing and $pricing gets undef on + exception $val }; $PRICING->set($pricing); # Pause between requests: my $time = _time(); if ($time > $next_interval) { # Wait till next interval if curl time is greater than $IN +TERVAL. $next_interval += $INTERVAL while $next_interval < $time; } sleep $next_interval - $time; $next_interval += $INTERVAL; } } sub main_loop { # Local variable to limit lock time and prevent changes mid-comput +ation my $pricing = 0; while ($RUNNING->get()) { $pricing = $PRICING->get(); # Optional - I don't know what you are doing with pricing, you + might want # to use 0 or undef to signal a request error (i.e., out-of-da +te data). next if !defined($pricing) or $pricing == 0; # Do something with $pricing; print "$pricing\n"; sleep 1; # Work simulation # return if QUIT CONDITION; } } my $thr = MCE::Hobo->create({ void_context => 1 }, \&price_thread); eval { main_loop() }; $RUNNING->set(0); $thr->join();