Re: Running subroutines at specific times
by blazar (Canon) on Apr 20, 2006 at 16:15 UTC
|
Seems like an event driven thing... but do you want the code in the various subs to run asynchronously? Can it possibly last more than the given amount of time? if so then you {c,sh}ould fork or use threads. Else you may be interested in alarm.
All in all seems more like stuff for cron. In perl, you may just have an infinite loop with a sleep 1 holding a counter. If, say, $counter % $interval == 0 then this will trigger the wanted action. Of course you can and probably want to have @interval or %interval instead of $interval.
| [reply] [d/l] [select] |
|
|
Thanks, let me add a little more detail.
I currently have a script which fires of a load of threads, to do SNMP polls on particular devices, each poll getting its own thread. I dont want to have a thread per device constantly running, especially if all its doing is sleeping.
So I suppose what I'm after is the ability to fire the same routine of (as a thread) every 20 seconds for device A, every 30 seconds for device B etc.
I was planning on reading in the device -> polling rate realtionship from a file. So it has to be a little dynamic.
Thanks again.
| [reply] |
|
|
| [reply] |
Re: Running subroutines at specific times
by saintmike (Vicar) on Apr 20, 2006 at 16:46 UTC
|
POE provides a framework for this kind of thing and much much more:
2006/04/20 10:57:59 sub10
2006/04/20 10:57:59 sub15
2006/04/20 10:58:09 sub10
2006/04/20 10:58:14 sub15
2006/04/20 10:58:19 sub10
2006/04/20 10:58:29 sub10
2006/04/20 10:58:29 sub15
use POE;
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init($DEBUG);
POE::Session->create(
inline_states => {
_start => sub {
$poe_kernel->yield("sub10");
$poe_kernel->yield("sub15");
},
sub10 => \&sub10,
sub15 => \&sub15,
});
$poe_kernel->run();
sub sub10 {
DEBUG "sub10";
$poe_kernel->delay("sub10", 10);
}
sub sub15 {
DEBUG "sub15";
$poe_kernel->delay("sub15", 15);
}
| [reply] [d/l] |
Re: Running subroutines at specific times
by jdhedden (Deacon) on Apr 20, 2006 at 16:15 UTC
|
| [reply] |
|
|
Thanks, let me add a little more detail.
I currently have a script which fires of a load of threads, to do SNMP polls on particular devices, each poll getting its own thread. I dont want to have a thread per device constantly running, especially if all its doing is sleeping.
So I suppose what I'm after is the ability to fire the same routine of (as a thread) every 20 seconds for device A, every 30 seconds for device B etc.
I was planning on reading in the device -> polling rate realtionship from a file. So it has to be a little dynamic.
| [reply] |
|
|
Thanks, let me add a little more detail.
Whatever the details may be, you already explained them in this post of which this one is a dupe, which is the reason why I and apparently others downvoted it. Regardless of the details, it seems to me that people supplied enough input already, are you having problems with any of these suggestions? I see that saintmike supplied a complete example, and BrowserUk suggested another approach, which should be more near to your original attempts. If you're having any specific problem with those suggestions, feel free to ask for further clarification...
| [reply] |
Re: Running subroutines at specific times
by salva (Canon) on Apr 20, 2006 at 16:23 UTC
|
You can use an event based framework like Event to do that. The repeat.t script on the demo directory from this module shows you how to set timers.
As your requirements are quite simple, you can also write a simple scheduler yourself around the sleep function. | [reply] [d/l] [select] |
Re: Running subroutines at specific times
by BrowserUk (Patriarch) on Apr 20, 2006 at 23:21 UTC
|
I dont want to have a thread per device constantly running, especially if all its doing is sleeping.
Why not?
This would be how I would do it. Note, I've no way to test the SNMP stuff, so I've just cleaned up the code you posted elsewhere.
#! perl
use strict;
use threads;
use threads::shared;
use Net::SNMP;
sub polldevice {
my( $running, $stop, $host, $community, $delay ) = @_;
++$running;
my( $session, $error ) = Net::SNMP->session(
Hostname => $host, Community => $community
) or die "session error:" . $session->error;
do {
my $result = $session->get_request(
"1.3.6.1.2.1.1.2.0", "1.3.6.1.2.1.2.1.0", "1.3.6.1.2.1.1.3
+.0"
) or die "request error: " . $session->error;
print "Testing ".$host."\n";
print "Number of interfaces: ".$result->{"1.3.6.1.2.1.2.1.0"}.
+"\n";
print "uptime: " . $result->{"1.3.6.1.2.1.1.3.0"}."\n";
print "sysOID: " . $result->{"1.3.6.1.2.1.1.2.0"}."\n";
} while not $stop and sleep $delay;
$session->close;
--$running;
}
my $stop :shared = 0;
my $running :shared = 0;
while( <DATA> ) {
async{ \&polldevice, $stop, split ' ' }->detach;
}
$SIG{INT} = sub{ $stop = 1 };
sleep 1 until $stop;
sleep 1 while $running;
__DATA__
192.168.1.50 public 10
192.168.1.1 public 25
192.168.1.2 public 60
192.168.1.3 public 45
192.168.1.4 public 12
192.168.1.5 public 59
192.168.1.6 public 01
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: Running subroutines at specific times
by TedPride (Priest) on Apr 20, 2006 at 17:06 UTC
|
Just store this as a queue of arrays, each array containing a sub ref, next timestamp to run the sub, and interval. Then sleep for however many seconds until the next item in the queue is up for running, add interval seconds to the timestamp, requeue, and run the sub. Rinse and repeat. All you need is a priority queue (or heap) module and about 5 minutes of elementary programming.
Of course, if this is an ongoing thing and needs to run 24/7, you may wish to do what blazar suggests and use cron, which was designed specifically for doing this sort of thing. | [reply] |