Python: run a function at set interval while program runs - python-3.x

I have a program that will be running 24/7 (assuming no server crashes). The program waits for users of a chat channel to issue commands, then it does several things based on the command issued and user permissions. This program will use and update data from Tuesday 10AM till next Tuesday 9AM, at which point, at 9AM, it will need to wipe the data and start over for the next week cycle.
I'm having trouble finding a way to implement the weekly reset though. I could restart the program every week, but was wondering if there is a way to run a background process that executes a function at a set interval (one week in this case). I was thinking of using a thread to keep track of time, and when a week has passed, have the thread execute the data wipe function. But wouldn't this be an unnecessarily expensive operation? Having a thread running at all times keeping track of passing time seems like a brute force solution.
I would greatly appreciate some pointers on how to go about doing this.

from datetime import datetime
next_wipe = get_next_wipe_datetime() # typically Tue. 9am
...
cmd = read_chat_channel()
if datetime.now() > next_wipe:
next_wipe = get_next_wipe_datetime()
do_wipe()
process(cmd)

Related

I have a program that connects to a data stream. How can I control it to only operate from Sunday 5pm to Friday 5pm each week?

So, Im creating a program to use with my broker's API, I connect to a trade stream and get data constantly.
Sicne the Forex market is closed from Friday 5pm to Sunday 5pm, I need my program to stop streaming data during this time.
I've tried many things, but I am unsure what way it right.
At the moment, the most logical way was to create a secondary file that controlled the time and date. It works for the first set (turning on the program at a certain time) but will not turn off because the first program is in the middle of a loop. Once I close the loop, the second program springs into action.
Here is a very simple concept program just to give you an idea of what I'm going for.
import datetime
import time
import os
friday = 4
fri_time = datetime.time(16,55)
sunday = 6
sun_time = datetime.time(17,05)
if datetime.date.today().weekday() == sunday:
if datetime.datetime.now().time() >= sun_time:
print('market is now open')
os.system(r'C:\Users\clay\Desktop\MyPy\broker\App_V2.0.py')
else:
pass
if datetime.date.today().weekday() == friday:
if datetime.datetime.now().time() >= fri_time:
print('market is now closed')
os.system('taskkill /f /im App_V2.0.py')
else:
pass
I've also tried adding it to the program itself but no matter what I am having a hard time controlling the program after it starts its loop. It only wants to kill the program after the loop has completed (or been closed manually)
How can you force terminate a loop controlled by time?
What is the best way to go about this?
Thank you!

sailsjs & laterjs task scheduling, initialization.. poll every x or sleep for x?

I am building an open sourced nodejs powered sprinkler system which will run on the raspberry pi and work with the OpenSprinkler Pi.
I am using:
sailsjs 0.9.3
laterjs - for schedule interpretation and maths
i created an issue awhile back on bunkats repo asking for him to explain this to me.. https://github.com/bunkat/later/issues/19
The end result will be a REST api interface between rpi and whatever front-end you decide to develop for. web/mobile/cli .. etc.
The way the scheduling component will work is values will be posted to the url /programs with a zone id, name, intial status (false), and a plain text human readable schedule phrase such as: every 12 hours starting on the 6th hour before 10 minutes (06:00 & 18:00 for 10 mins).
This schedule will be parsed, and stringified and stored in db as such:
{\"schedules\":[{\"h\":[6,18],\"m_b\":[10]}],\"exceptions\":[],\"error\":-1}
The other values are cleaned and stored as they were entered.
My question is:
how should I go about finding these schedules and determining their run time/date? I've got the scheduling part, and the run time down and working (run for 10 mins). I'm struggling with the theory behind efficiently retrieving the schedules though.
My initial thought was to have a interval every 1 mins poll the db...
setInterval(function(){
//get programs from db
//iterate through programs
//enable programs which start now?
}, 60000);
But this seems kind of illogical. I suppose that when the schedule is created a setInterval or setTimeout is created with the appropriate scheduling info.. but what happens if the rpi loses power, or those could eat up a bit of memory having all of these intervals hanging out there..
how will it handle existing schedules already in the db?
open source repo
of what i have so far (not much other than the creation api/models/Programs.js) is here:
https://github.com/RelativeMedia/nodesprinkler.git

Preventing cronjobs from overlapping

I have 3 different jobs set up in crontab (call them jobA, jobB, jobC) that run at different intervals and start at different times during the day. For example, jobA runs once per hour at 5 mins past the hour, jobB runs every 30 mins at 9 and 39 mins past the hour, and jobC runs every 15 mins. They are not dependent on each other, but for various reasons they can NOT be running at the same time.
The problem is that sometimes one of the jobs takes a long time to run and another one starts before the first one is done, causing issues.
Is there some way to queue or spool these jobs so that one will not start until the current running one has finished? I tried using this solution but this does not guarantee that the pending jobs will resume in the same order they were supposed to start. A queue would be best, but I cannot find anything about how to do this.
You can't do that using cron. Cron is used to run a specific command at specific time. You can do it by the solution you proposed, but that adds a lot more complexity.
I suggest, writing/coding the requirement in high level language like java and use a mutil-thread program to achieve what you need.
Control-m is another scheduling software, with a lot of other features as well. You would be able to integrate the above use-case in it.

whether to use job scheduler or sleep() function

I am confused whether to use cron job scheduler or use sleep function in the program itself. There are questions on this previously but I seem to have some different requirements form them.
I need some information from the previous run of the program so if I use cron to schedule
job I would have to store that information at some place and re-read it next time(this can make the program less scale-able if the size of this information grows).
I can also use sleep() but that will be using resources.
I will need to re-run the program every 10 mins or so. Which one is better to use.
Is there any other nice way of doing it which I may be missing.
In general you should use cron whenever you can for something like this.
The only problem I could foresee is if your program somehow took longer than 10 minutes to run, cron is going to call the next execution 10 minutes later anyway. This creates a really long race condition basically, where if you did sleep it would only start sleeping after the previous execution ended.
But assuming your program will take less time to run, I say go with cron.

How can I keep a RPG program running in memory?

I coded a monitoring program in RPG that checks if the fax/400 is operational.
And now I want this program to check every 15 minutes.
Instead of placing a job every 15 minutes in the job scheduler (which would be ugly to manage), I made the program wait between checks using DLYJOB.
Now how can I make this program "place itself" in memory so it keeps running?
(I thought of using SBMJOB, but I can't figure in which job queue I could place it.)
A good job queue to use for an endlessly running job would be QSYSNOMAX. That allows unlimited numbers of jobs to be running.
You could submit the job to that queue in your QSTRTUP program and it will simply remain running all the time.
Here what I have done in the past. There are two approaches to this.
Submit a new job every time the program runs with DLYJOB before it runs.
Create a loop and only end given a certain condition.
What I did with a Monitor MSGW program was the following:
PGM
DCL VAR(&TIME) TYPE(*CHAR) LEN(6)
DCL VAR(&STOPTIME) TYPE(*CHAR) LEN(6) +
VALUE('200000')
/* Setup my program (run only once) */
START:
/* Perform my actions */
RTVSYSVAL SYSVAL(QTIME) RTNVAR(&TIME)
IF COND(&TIME *GE &STOPTIME) THEN(GOTO CMDLBL(END))
DLYJOB DLY(180)
GOTO CMDLBL(START)
END:
ENDPGM
This will run continuously until 8:00 pm. Then I add this to the job scheduler to submit every morning.
As far as which jobq. I am using QINTER, but it could really be run anywhere. Make sure you choose a subsystem with enough available running jobs as this will take one.
The negative of running in QINTER if the program starts to hit 100% CPU, that will use up all of your interactive CPU and effectively locks up your system.
i know of 3 ways to that.
1) using Data queue, there is parm to tell it to wait endlessly and at time-interval.
2) using OVRDBF cmd, there is parm there to tell that it should not end or EOF, making your pgm to keep on waiting.
3) easiest to implement, sbmjob to call a pgm that loops forever eg with DOW 1=1, you can insert a code to check for certain time interval before it iterates. You can have your logic inside the loop that checks for fax, process it and then back to waiting.

Resources