diff --git a/webservices/cron.php b/webservices/cron.php new file mode 100644 index 0000000000..387a09611d --- /dev/null +++ b/webservices/cron.php @@ -0,0 +1,170 @@ + + * @author Romain Quetiez + * @author Denis Flaven + * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL + */ + +require_once('../approot.inc.php'); +require_once(APPROOT.'/application/application.inc.php'); +require_once(APPROOT.'/application/nicewebpage.class.inc.php'); +require_once(APPROOT.'/application/webpage.class.inc.php'); +require_once(APPROOT.'/application/clipage.class.inc.php'); + +require_once(APPROOT.'/application/startup.inc.php'); + + +function CronExec($oP, $aBackgroundProcesses, $bVerbose) +{ + $iStarted = time(); + $iMaxDuration = MetaModel::GetConfig()->Get('cron_max_execution_time'); + $iTimeLimit = $iStarted + $iMaxDuration; + + if ($bVerbose) + { + $oP->p("Planned duration = $iMaxDuration seconds"); + } + + $iCronSleep = MetaModel::GetConfig()->Get('cron_sleep'); + + while (time() < $iTimeLimit) + { + foreach ($aBackgroundProcesses as $oBackgroundProcess) + { + if ($bVerbose) + { + $oP->p("Processing asynchronous task: ".get_class($oBackgroundProcess)); + } + $sMessage = $oBackgroundProcess->Process($iTimeLimit); + if ($bVerbose && !empty($sMessage)) + { + $oP->p("Returned: $sMessage"); + } + } + if ($bVerbose) + { + $oP->p("Sleeping"); + } + sleep($iCronSleep); + } + if ($bVerbose) + { + $oP->p("Reached normal execution time limit (exceeded by ".(time()-$iTimeLimit)."s)"); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Main +// + +if (utils::IsModeCLI()) +{ + $oP = new CLIPage("iTop - Bulk import"); + + // Next steps: + // specific arguments: 'csvfile' + // + $sAuthUser = ReadMandatoryParam($oP, 'auth_user'); + $sAuthPwd = ReadMandatoryParam($oP, 'auth_pwd'); + if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd)) + { + UserRights::Login($sAuthUser); // Login & set the user's language + } + else + { + $oP->p("Access restricted or wrong credentials ('$sAuthUser')"); + exit; + } +} +else +{ + $_SESSION['login_mode'] = 'basic'; + require_once(APPROOT.'/application/loginwebpage.class.inc.php'); + LoginWebPage::DoLogin(); // Check user rights and prompt if needed + + $oP = new WebPage("iTop - CRON"); +} + + +// Enumerate classes implementing BackgroundProcess +// +$aBackgroundProcesses = array(); +foreach(get_declared_classes() as $sPHPClass) +{ + $oRefClass = new ReflectionClass($sPHPClass); + $oExtensionInstance = null; + if ($oRefClass->implementsInterface('iBackgroundProcess')) + { + if (is_null($oExtensionInstance)) + { + $oExecInstance = new $sPHPClass; + } + $aBackgroundProcesses[] = $oExecInstance; + } +} + + +$bVerbose = utils::ReadParam('verbose', false); + +if ($bVerbose) +{ + $aDisplayProcesses = array(); + foreach ($aBackgroundProcesses as $oExecInstance) + { + $aDisplayProcesses[] = get_class($oExecInstance); + } + $sDisplayProcesses = implode(', ', $aDisplayProcesses); + $oP->p("Background processes: ".$sDisplayProcesses); +} + +$sLockName = 'itop.cron.php'; + +$oP->p("Starting: ".time()); +$res = CMDBSource::QueryToScalar("SELECT GET_LOCK('$sLockName', 1)");// timeout = 1 second (see also IS_FREE_LOCK) +if (is_null($res)) +{ + // TODO - Log ? + $oP->p("ERROR: Failed to acquire the lock '$sLockName'"); +} +elseif ($res === '1') +{ + // The current session holds the lock + try + { + CronExec($oP, $aBackgroundProcesses, $bVerbose); + } + catch(Exception $e) + { + // TODO - Log ? + $oP->p("ERROR:".$e->GetMessage()); + } + $res = CMDBSource::QueryToScalar("SELECT RELEASE_LOCK('$sLockName')"); +} +else +{ + // Lock already held by another session + // Exit silently + $oP->p("Already running..."); +} +$oP->p("Exiting: ".time()); + +$oP->Output(); +?>