execute every 15 min

L

luc

I have a perl program that downloads the value of some shares on the
Brussels stock market. The problem is that every 15 minutes the value
changes. How would I go about changing this program so that it automatically
starts up at 9.30(finishes at 16.00(market closed)) and every 15 minutes
would download the prices and put them in diffrent files, so that I would
have 32 files? With this data you could easily see the flow of the share.
 
J

Jürgen Exner

luc said:
I have a perl program that downloads the value of some shares on the
Brussels stock market. The problem is that every 15 minutes the value
changes. How would I go about changing this program so that it
automatically starts up at 9.30

That's not possible. How could a program determine if it is supposed to run
without being run?
This is a job for cron.
(finishes at 16.00(market closed))

Just have your program check what the current time is (see time() and
localtime()) and have it terminate after 16:00.
and
every 15 minutes would download the prices

While you could use sleep(15*60) a better approach would probably be to use
the OS tools that are made for exactly that purpose. Again, cron is your
friend.
and put them in diffrent
files, so that I would have 32 files?

jue
 
J

Jeff Boes

luc said:
I have a perl program that downloads the value of some shares on the
Brussels stock market. The problem is that every 15 minutes the value
changes. How would I go about changing this program so that it automatically
starts up at 9.30(finishes at 16.00(market closed)) and every 15 minutes
would download the prices and put them in diffrent files, so that I would
have 32 files? With this data you could easily see the flow of the share.

As noted elsewhere in this thread, if the program's not running, it
can't determine if it should be running. You need cron for that, or else
the program has to *be* running, all the time, and just "wake up"
periodically to do its thing.

[Code examples which follow are schematic, not intended to run without
significant modification to suit your local purpose.]

The simple approach:

#!/usr/bin/perl -w
use strict;

while (1) {
# Do your check here.
sleep (15 * 60);
}

This has the advantage of being extremely portable. However, it has the
disadvantage of only ensuring that the *start* of one check will follow
the *end* of the previous check by *at least* 15 minutes. If a download
takes two minutes, then the start of each download will fall 17 minutes
after the last one.


A more complex approach involves setting an "alarm clock" signal to wake
your process:


#!/usr/bin/perl -w
use strict;
use POSIX;

$SIG{ALRM} = \&set_alarm_and_snooze;

set_alarm_and_snooze;

sub set_alarm_and_snooze {
alarm(15 * 60);
# Do your download here.
POSIX::pause;
}


This approach ensures that the starts of two downloads will be separated
by 15 minutes, but it also has a couple of problems:

1. If a download takes longer than 15 minutes, the next download may
interrupt it.
2. If this script runs for a very long time (e.g., many days), you may
run out of memory, because it's recursive!

These examples are presented to show that a self-contained approach may
not be your best bet. Were this my task, I'd stick with cron -- but a
Windows or other OS may not provide such features (although I've had
success using the Windows task scheduler in XP, and I'm pretty sure that
other contemporary Windows versions have similar things).

Failing that, you will almost certainly end up at CPAN. Some promising
items there include Proc::Daemon, Coro::Timer, Prima::Timer, etc. I've
not used these -- I used the Event package instead, which provides a lot
more functionality but may be complete overkill for you.
 
J

Jim Cochrane

As noted elsewhere in this thread, if the program's not running, it
can't determine if it should be running. You need cron for that, or else
the program has to *be* running, all the time, and just "wake up"
periodically to do its thing.

Yep - If a cron-like tool is not available you need to either write your
script to run constantly and do its own timing (sort of like writing your
own cron-daemon that is limited to just one hard-coded task) or write a
driver program or script that runs constantly, does the timing, and calls
the script when needed.
...
A more complex approach involves setting an "alarm clock" signal to wake
your process:

#!/usr/bin/perl -w
use strict;
use POSIX;

$SIG{ALRM} = \&set_alarm_and_snooze;

set_alarm_and_snooze;

sub set_alarm_and_snooze {
alarm(15 * 60);
# Do your download here.
POSIX::pause;
}

This approach ensures that the starts of two downloads will be separated
by 15 minutes, but it also has a couple of problems:

1. If a download takes longer than 15 minutes, the next download may
interrupt it.

My guess is that it is so unlikely that a download will take longer than 15
minutes that the script can be written to assume this will rarely occur and
when it does occur, do the following: If it's time to download but the
last download is still ocurring, skip the current download - i.e., wait
until the next alarm to do the download. Allowing the in-progress download
to finish will avoid possible data corruption problems.
2. If this script runs for a very long time (e.g., many days), you may
run out of memory, because it's recursive!

I don't think it would be particularly difficult to write the script such
that it manages resources well - so that its memory use does not constantly
increase.
These examples are presented to show that a self-contained approach may
not be your best bet.

I think this approach is workable if no cron utility is available, as long
as the OP has the resources (skill and time, or money and time if he
decides to hire someone to do it) to implement it. It's not an easy task,
but finding the right modules might make it not particularly difficult.
Were this my task, I'd stick with cron -- but a
Windows or other OS may not provide such features (although I've had
success using the Windows task scheduler in XP, and I'm pretty sure that
other contemporary Windows versions have similar things).

Failing that, you will almost certainly end up at CPAN. Some promising
items there include Proc::Daemon, Coro::Timer, Prima::Timer, etc. I've
not used these -- I used the Event package instead, which provides a lot
more functionality but may be complete overkill for you.

Yes, after some exploration of CPAN, if you (the OP) are unsure which
module to use, a question here (or in the modules group) would probably be
in order. You also might want to look at the "submodules" under Finance::.
It's possible that some of this functionality is already available.
 
W

Web Surfer

[This followup was posted to comp.lang.perl.misc]

I have a perl program that downloads the value of some shares on the
Brussels stock market. The problem is that every 15 minutes the value
changes. How would I go about changing this program so that it automatically
starts up at 9.30(finishes at 16.00(market closed)) and every 15 minutes
would download the prices and put them in diffrent files, so that I would
have 32 files? With this data you could easily see the flow of the share.


On UNIX systems you can use the "cron" facility to run programs at
specified times.
 
D

Dieter D'Hoker

luc said:
I have a perl program that downloads the value of some shares on the
Brussels stock market. The problem is that every 15 minutes the value
changes. How would I go about changing this program so that it
automatically starts up at 9.30(finishes at 16.00(market closed)) and
every 15 minutes would download the prices and put them in diffrent
files, so that I would have 32 files? With this data you could easily
see the flow of the share.

Just make a mainloop that checks what time it is every loop and then decides
what to do,
make sure to put sleep(1); at the end of it otherwise it would consume 100%
of CPU,
and there is no point in checking every microsecond to see if the time has
changed :)

The following is not working perlcode but gives you an idea :)

my $lasttime;

while(1){
sleep 1;
my $currenttime = getcurrentime();
if ($currenttime >= 1600 or $currenttime < 0930 ) {$lasttime =
$currenttime;next;}
elsif ( ($currentime - $lasttime) >= 0015 ) {fetchstocks();}
$lasttime = $currenttime;
}
 
J

Joe Smith

Jeff said:
while (1) {
# Do your check here.
sleep (15 * 60);
}

This has the advantage of being extremely portable. However, it has the
disadvantage of only ensuring that the *start* of one check will follow
the *end* of the previous check by *at least* 15 minutes. If a download
takes two minutes, then the start of each download will fall 17 minutes
after the last one.

$sleep_seconds = 15 * 60
while (1) {
...
sleep ($sleep_seconds - (time % $sleep_seconds));
}

-Joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top