I need some advice on the best way to do this. I am developing a web application that monitors a data stream and adds that to a database. It then checks it against a ruleset for specific criteria. If one of these criteria is met, it needs to run a specific query on that same entry x minutes later. (x is set by user config).
I was thinking a way to do it would be to have it create cron jobs but first, I don't know how to do that, secondly, I was wondering if there is a better way.
Entry received -> Matches criteria -> Wait X minutes -> Execute another query.
I need it to do this without pausing the script because lots of data would be coming in so if it waited for 10 minutes it wouldn't ever process all the data.
Thanks!
Don't create multiple cron jobs.
Store the users configuration as a timestamp (in the future), and have one cron job that runs frequently (every 1 minute is the maximum) and will query the list of user configurations to see if another query needs to be executed.
Store the last execution time of the cron job and have it query the list -
SELECT * FROM `pending_queries` WHERE `execution_ts` <= {$last_execution_ts}
Should some of the queries take a longer time to execute, you run the risk of potentially overlapping the execution time of one or more queries. To solve this, as soon as you extract data on a pending query, you should mark it with an is_processing
flag as some other field in the row. So your query now becomes-
SELECT * FROM `pending_queries` WHERE
`execution_ts` <= {$last_Execution_ts} AND `is_processing`=0
Finally, after processing a query, you should delete it from the pending_queries
table.
Learn cronjob.
If you want to wait for 10 minutes without stopping the script execution, the user will have to wait 10 mins.
If you want to do this operation without bothering the user, you can create a child process that will handle this operation. The process won't stop but interaction with the user will be end. In the child process you can pause the script for 10 mins.
How to create a child process: http://php.net/manual/en/function.pcntl-fork.php
How to pause the process: http://php.net/manual/en/function.sleep.php
I solved similar problem for myself using JS/JQuery and PHP. Here is kind of pseudo code for it:
pingTimer = 0;
function pingTimerIncrement() {
//your criterias to be checked here either using plain
//JS or AJAX to do it on server side
if (criterias met) {
pingTimer += 1; //increase by 1 minute
if (pingTimer == YOUR_USER_CONFIG_MINUTES) {
//code to update your database using ajax
}
}
}
$(function() {
var timerInterval = setInterval("pingTimerIncrement()", 6000); //1 minute
});
the other way if you dont want to use JS/JQuery then use cronjob
If there are many similar tasks like this, you can make a table for tasks and populate it when needed.
Then, cron script that runs every minute can select all entries from this table with execution time less or equal than current time and run them.