I take a look at what been going on here and i wonder if one thing is possible with this.
I work on a project with CI4 which relays heavily on cron to fetch the data from APIs. We're fetching data form about 30 endpoints every minute. And each of the request takes a lot of time to complete the processing. So in other to achieve those I need to spawn a lot of processes to work at the same time. So I have a single command which executed the multiple instances of other command by using something like this
/** * Spark Exec * * @param string $sparkCommand Command * @param int|null $timeout Timeout */functionspark_exec(string$sparkCommand, ?int$timeout = null): void
{
$command = '';
if ($timeout) {
$command .= 'timeout ' . $timeout . '';
}
$command .= '"' . PHP_BINARY . '" -c "' . (get_cfg_var('cfg_file_path') ?: PHP_CONFIG_FILE_PATH) . '" ' . ROOTPATH . 'spark ' . $sparkCommand . ' > /dev/null &';
exec($command);
}And the problem is that I cannot have more that one process working working with the same endpoint and writing the same data db so I have mechanism to put some locks in place so I use files to track the locking
/** * Crates the Lockfile with the current class name * * @param string|null $identifier String to append to the filename * * @return bool|resource Locked file if successful otherwise false */publicstaticfunctionlock(?string$identifier = null)
{
//Add leading dash to identifier if it is setif (isset($identifier)) {
$identifier = '-' . $identifier;
}
//Get the locks file directory$lockDir = WRITEPATH . 'cron/locks/';
//Create the locks file directory if it does not existif (! file_exists($lockDir)) {
mkdir($lockDir, 0755, true);
}
//Get the filename$filename = $lockDir . $identifier . '.lock';
//Open the file for writing to lock it$lock = fopen($filename, 'wb');
if ($lock === false) {
// Unable to open file, check that you have permissions to open/writeCLI::error('Unable to write the lock file');
exit;
}
if (flock($lock, LOCK_EX | LOCK_NB) === false) {
// Lock is already in use by another processCLI::error('Another instance is already running');
exit;
}
//Return the locked filereturn$lock;
}
/** * Closes the file removing the lock * * @param resource $lock Lock */publicstaticfunctionunlock(&$lock): void
{
//Check if lock existif ($lock && get_resource_type($lock) !== 'Unknown') {
//Get the filename$metaData = stream_get_meta_data($lock);
$filename = $metaData['uri'];
//Close the file to remove the lockfclose($lock);
//Remove the lock fileunlink($filename);
}
}
/** * Check if lock files with set prefix exist * * @param string $prefix filename prefix * * @return bool Ture if there are lock files otherwise false */publicstaticfunctionisWorking(string$prefix): bool
{
$result = false;
//We read the locks directory if there are lock files it means we're still workingif ($openDir = opendir(WRITEPATH . 'cron/locks/')) {
while (($file = readdir($openDir)) !== false) {
if (substr($file, 0, strlen($prefix)) === $prefix) {
$result = true;
break;
}
}
}
return$result;
}I wonder if there are plans to be able to achieve something similar with the scheduler here. From looking at the code I believe all the scheduled actions run on a single thread. So for example if I have 2 tasks scheduled to run first runs every 5 minutes second task runs every minute. And if first task takes more that 1 minute to be completed. On the next cron run second task will be started but once the first process finishes with task 1 it will continue with the second task in the first process and the order of execution is completely broken.
And there are a lot of real case situations where long running tasks are needed. One example is generating sitemap from the database for the huge site
I take a look at what been going on here and i wonder if one thing is possible with this.
I work on a project with CI4 which relays heavily on cron to fetch the data from APIs. We're fetching data form about 30 endpoints every minute. And each of the request takes a lot of time to complete the processing. So in other to achieve those I need to spawn a lot of processes to work at the same time. So I have a single command which executed the multiple instances of other command by using something like this
And the problem is that I cannot have more that one process working working with the same endpoint and writing the same data db so I have mechanism to put some locks in place so I use files to track the locking
I wonder if there are plans to be able to achieve something similar with the scheduler here. From looking at the code I believe all the scheduled actions run on a single thread. So for example if I have 2 tasks scheduled to run first runs every 5 minutes second task runs every minute. And if first task takes more that 1 minute to be completed. On the next cron run second task will be started but once the first process finishes with task 1 it will continue with the second task in the first process and the order of execution is completely broken.
And there are a lot of real case situations where long running tasks are needed. One example is generating sitemap from the database for the huge site