Scalr_SchedulerTask::execute PHP Method

execute() public method

Executes the task
public execute ( $manual = false ) : boolean
return boolean $manual optional Whether task is executed by manual
    public function execute($manual = false)
    {
        $farmRoleNotFound = false;
        $logger = $this->getLogger() ?: \Scalr::getContainer()->logger(__CLASS__);
        switch ($this->type) {
            case self::LAUNCH_FARM:
                try {
                    $farmId = $this->targetId;
                    $DBFarm = DBFarm::LoadByID($farmId);
                    if ($DBFarm->Status == FARM_STATUS::TERMINATED) {
                        // launch farm
                        Scalr::FireEvent($farmId, new FarmLaunchedEvent(true, null, ['service.scheduler.task_id' => $this->id]));
                        $logger->info(sprintf("Farm #{$farmId} successfully launched"));
                    } elseif ($DBFarm->Status == FARM_STATUS::RUNNING) {
                        // farm is running
                        $logger->info(sprintf("Farm #{$farmId} is already running"));
                    } else {
                        // farm can't be launched
                        $logger->info(sprintf("Farm #{$farmId} can't be launched because of it's status: {$DBFarm->Status}"));
                    }
                } catch (Exception $e) {
                    $farmRoleNotFound = true;
                    $logger->info(sprintf("Farm #{$farmId} was not found and can't be launched"));
                }
                break;
            case self::TERMINATE_FARM:
                try {
                    // get config settings
                    $farmId = $this->targetId;
                    $deleteDNSZones = (int) $this->config['deleteDNSZones'];
                    $deleteCloudObjects = (int) $this->config['deleteCloudObjects'];
                    $keepCloudObjects = $deleteCloudObjects == 1 ? 0 : 1;
                    $DBFarm = DBFarm::LoadByID($farmId);
                    if ($DBFarm->Status == FARM_STATUS::RUNNING) {
                        // Terminate farm
                        Scalr::FireEvent($farmId, new FarmTerminatedEvent($deleteDNSZones, $keepCloudObjects, false, $keepCloudObjects, true, null, ['service.scheduler.task_id' => $this->id]));
                        $logger->info(sprintf("Farm successfully terminated"));
                    } else {
                        $logger->info(sprintf("Farm #{$farmId} can't be terminated because of it's status"));
                    }
                } catch (Exception $e) {
                    $farmRoleNotFound = true;
                    $logger->info(sprintf("Farm #{$farmId} was not found and can't be terminated"));
                }
                break;
            case self::FIRE_EVENT:
                switch ($this->targetType) {
                    case self::TARGET_FARM:
                        $DBFarm = DBFarm::LoadByID($this->targetId);
                        $farmId = $DBFarm->ID;
                        $farmRoleId = null;
                        $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE `status` IN (?,?) AND farm_id = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId));
                        break;
                    case self::TARGET_ROLE:
                        $farmRoleId = $this->targetId;
                        $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE `status` IN (?,?) AND farm_roleid = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId));
                        break;
                    case self::TARGET_INSTANCE:
                        $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE `status` IN (?,?) AND farm_roleid = ? AND `index` = ? ", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $this->targetId, $this->targetServerIndex));
                        break;
                }
                if (count($servers) == 0) {
                    throw new Exception("No running Servers found. Event was not fired.");
                }
                foreach ($servers as $server) {
                    /* @var $dbServer DBServer */
                    $dbServer = DBServer::LoadByID($server['server_id']);
                    Scalr::FireEvent($dbServer->farmId, new CustomEvent($dbServer, $this->config['eventName'], (array) $this->config['eventParams']));
                }
                break;
            case self::SCRIPT_EXEC:
                // generate event name
                $eventName = "Scheduler (TaskID: {$this->id})";
                if ($manual) {
                    $eventName .= ' (manual)';
                }
                try {
                    if (!\Scalr\Model\Entity\Script::findPk($this->config['scriptId'])) {
                        throw new Exception('Script not found');
                    }
                    // get executing object by target_type variable
                    switch ($this->targetType) {
                        case self::TARGET_FARM:
                            $DBFarm = DBFarm::LoadByID($this->targetId);
                            $farmId = $DBFarm->ID;
                            $farmRoleId = null;
                            $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE is_scalarized = 1 AND `status` IN (?,?) AND farm_id = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmId));
                            break;
                        case self::TARGET_ROLE:
                            $farmRoleId = $this->targetId;
                            $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE is_scalarized = 1 AND `status` IN (?,?) AND farm_roleid = ?", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $farmRoleId));
                            break;
                        case self::TARGET_INSTANCE:
                            $servers = $this->db->GetAll("SELECT server_id FROM servers WHERE is_scalarized = 1 AND `status` IN (?,?) AND farm_roleid = ? AND `index` = ? ", array(SERVER_STATUS::INIT, SERVER_STATUS::RUNNING, $this->targetId, $this->targetServerIndex));
                            break;
                    }
                    if ($servers) {
                        $scriptSettings = array('version' => $this->config['scriptVersion'], 'scriptid' => $this->config['scriptId'], 'timeout' => $this->config['scriptTimeout'], 'issync' => $this->config['scriptIsSync'], 'params' => serialize($this->config['scriptOptions']), 'type' => Scalr_Scripting_Manager::ORCHESTRATION_SCRIPT_TYPE_SCALR);
                        // send message to start executing task (starts script)
                        foreach ($servers as $server) {
                            $DBServer = DBServer::LoadByID($server['server_id']);
                            $msg = new Scalr_Messaging_Msg_ExecScript($eventName);
                            $msg->setServerMetaData($DBServer);
                            $script = Scalr_Scripting_Manager::prepareScript($scriptSettings, $DBServer);
                            if ($script) {
                                $DBServer->executeScript($script, $msg);
                                $this->getContainer()->auditlogger->log('script.execute', $script, $DBServer, $this->id);
                            }
                        }
                    } else {
                        $farmRoleNotFound = true;
                    }
                } catch (Exception $e) {
                    // farm or role not found.
                    $farmRoleNotFound = true;
                    $logger->warn(sprintf("Farm, role or instances were not found, script can't be executed"));
                }
                break;
        }
        return !$farmRoleNotFound;
    }

Usage Example

Ejemplo n.º 1
0
 public function OnStartForking()
 {
     // start cron, which runs scripts by it's schedule queue
     try {
         $db = \Scalr::getDb();
         // set status to "finished" for active tasks, which ended or executed once
         $db->Execute("UPDATE scheduler SET `status` = ? WHERE\n                `status` = ? AND (\n                    CONVERT_TZ(`end_time`,'SYSTEM',`timezone`) < CONVERT_TZ(NOW(),'SYSTEM',`timezone`) OR\n                    (CONVERT_TZ(`last_start_time`,'SYSTEM',`timezone`) < CONVERT_TZ(NOW(),'SYSTEM',`timezone`) AND `restart_every` = 0)\n                )", array(Scalr_SchedulerTask::STATUS_FINISHED, Scalr_SchedulerTask::STATUS_ACTIVE));
         // get active tasks: first run (condition and last_start_time is null), others (condition and last_start_time + interval * 0.9 < now())
         $taskList = $db->GetAll("SELECT *\n                FROM scheduler\n                WHERE\n                    `status` = ? AND\n                    (`end_time` IS NULL OR CONVERT_TZ(`end_time`,'SYSTEM',`timezone`) > CONVERT_TZ(NOW(),'SYSTEM',`timezone`)) AND\n                    (`start_time` IS NULL OR CONVERT_TZ(`start_time`,'SYSTEM',`timezone`) <= CONVERT_TZ(NOW(),'SYSTEM',`timezone`)) AND\n                    (\n                        `last_start_time` IS NULL OR\n                        `last_start_time` IS NOT NULL AND `start_time` IS NULL AND (CONVERT_TZ(last_start_time + INTERVAL restart_every MINUTE, 'SYSTEM', `timezone`) < CONVERT_TZ(NOW(),'SYSTEM',`timezone`)) OR\n                        `last_start_time` IS NOT NULL AND `start_time` IS NOT NULL AND (CONVERT_TZ(last_start_time + INTERVAL (restart_every * 0.9) MINUTE, 'SYSTEM', `timezone`) < CONVERT_TZ(NOW(),'SYSTEM',`timezone`))\n                    )\n                ORDER BY IF (last_start_time, last_start_time, start_time), order_index ASC\n            ", array(Scalr_SchedulerTask::STATUS_ACTIVE));
         if (!$taskList) {
             $this->Logger->info(_("There is no tasks to execute in scheduler table"));
             exit;
         }
         foreach ($taskList as $task) {
             // check account status (active or inactive)
             try {
                 if (Scalr_Account::init()->loadById($task['account_id'])->status != Scalr_Account::STATUS_ACTIVE) {
                     continue;
                 }
             } catch (Exception $e) {
                 $this->Logger->info("Invalid scheduler task #{$task['id']}: {$e->getMessage()}");
             }
             if ($task['last_start_time'] && $task['start_time']) {
                 // try to auto-align time to start time
                 $startTime = new DateTime($task['start_time']);
                 $startTime->setTimezone(new DateTimeZone($task['timezone']));
                 $currentTime = new DateTime('now', new DateTimeZone($task['timezone']));
                 $offset = $startTime->getOffset() - $currentTime->getOffset();
                 $num = ($currentTime->getTimestamp() - $startTime->getTimestamp() - $offset) / ($task['restart_every'] * 60);
                 // num should be less than 0.5
                 if (floor($num) != round($num, 0, PHP_ROUND_HALF_UP)) {
                     continue;
                 }
             }
             $taskObj = new Scalr_SchedulerTask();
             $taskObj->loadById($task['id']);
             if ($taskObj->execute()) {
                 // convert_tz
                 $taskObj->updateLastStartTime();
                 $this->Logger->info(sprintf("Task {$taskObj->id} successfully sent"));
             }
         }
     } catch (Exception $e) {
         $this->Logger->warn(sprintf("Can't execute task {$task['id']}. Error message: %s", $e->getMessage()));
     }
 }