protected function _run()
 {
     // Run in a loop until we run out of time, or breakflag is set
     $registry = AliceFactory::getConfiguration();
     $timer = AliceFactory::getTimer();
     // Let's check if I already have a stack coming from previous call
     $this->log = $registry->get('volatile.alice.logToAnalyze');
     $this->checks = $registry->get('volatile.alice.' . $this->checksName . '.checks', array());
     $this->totalChecks = $registry->get('volatile.alice.' . $this->checksName . '.totalChecks', 0);
     // No incoming stack, let's build it now
     if (!$this->checks) {
         $this->checks = AliceUtilScripting::getChecksStack($this->checksName);
         $this->totalChecks = count($this->checks);
     }
     while ($timer->getTimeLeft() > 0 && !$registry->get('volatile.breakflag', false) && count($this->checks)) {
         if ($this->getState() == 'postrun') {
             AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, __CLASS__ . " :: Already finished");
             $this->setStep("-");
             $this->setSubstep("");
             break;
         } else {
             // Did I finished every check?
             if (!$this->checks) {
                 return;
             }
             $error = '';
             $solution = '';
             $className = array_shift($this->checks);
             $check = new $className($this->log);
             $this->setSubstep($check->getName());
             $this->progress = ($this->totalChecks - count($this->checks)) / $this->totalChecks;
             // Well, check, do your job!
             try {
                 $check->check();
             } catch (Exception $e) {
                 // Mhm... log didn't passed the check. Let's save the error and the suggested solution
                 $error = $e->getMessage();
                 $solution = $check->getSolution();
             }
             $result = $check->getResult();
             $feedback = $registry->get('volatile.alice.feedback', array());
             $feedback[] = array('check' => $check->getName(), 'result' => $result, 'error' => $error, 'solution' => $solution);
             $registry->set('volatile.alice.feedback', $feedback);
             unset($check);
         }
     }
     // Let's save everything
     $registry->set('volatile.alice.requirements.checks', $this->checks);
     $registry->set('volatile.alice.requirements.totalChecks', $this->totalChecks);
     $this->setState('postrun');
 }
 /**
  * The public interface to an engine part. This method takes care for
  * calling the correct method in order to perform the initialisation -
  * run - finalisation cycle of operation and return a proper reponse array.
  *
  * @param   int     $nesting
  *
  * @return  array    A Reponse Array
  */
 public final function tick($nesting = 0)
 {
     $configuration = AliceFactory::getConfiguration();
     $timer = AliceFactory::getTimer();
     // Call the right action method, depending on engine part state
     switch ($this->getState()) {
         case "init":
             $this->_prepare();
             $breakFlag = $configuration->set('volatile.breakflag', false);
             break;
         case "prepared":
             $this->_run();
             break;
         case "running":
             $this->_run();
             break;
         case "postrun":
             $this->_finalize();
             $breakFlag = $configuration->set('volatile.breakflag', false);
             break;
     }
     // If there is still time, we are not finished and there is no break flag set, re-run the tick()
     // method.
     $breakFlag = $configuration->get('volatile.breakflag', false);
     if (!in_array($this->getState(), array('finished', 'error')) && $timer->getTimeLeft() > 0 && !$breakFlag && $nesting < 20 && $this->nest_logging) {
         // Nesting is only applied if $this->nest_logging == true (currently only Kettenrad has this)
         $nesting++;
         if ($this->nest_logging) {
             AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "*** Batching successive steps (nesting level {$nesting})");
         }
         $out = $this->tick($nesting);
     } else {
         // Return the output array
         $out = $this->_makeReturnTable();
         // Things to do for nest-logged parts (currently, only Kettenrad is)
         if ($this->nest_logging) {
             if ($breakFlag) {
                 AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "*** Engine steps batching: Break flag detected.");
             }
             // Reset the break flag
             $configuration->set('volatile.breakflag', false);
             // Log that we're breaking the step
             AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "*** Batching of engine steps finished. I will now return control to the caller.");
             // Enforce minimum execution time
             $timer = AliceFactory::getTimer();
             $timer->enforce_min_exec_time(true);
         }
     }
     // Send a Return Table back to the caller
     return $out;
 }
Esempio n. 3
0
 protected function _run()
 {
     AliceUtilLogger::openLog($this->tag);
     set_error_handler('aliceBackupErrorHandler');
     // Maybe we're already done or in an error state?
     if ($this->getError() || $this->getState() == 'postrun') {
         return;
     }
     // Set running state
     $this->setState('running');
     // Initialize operation counter
     $registry = AliceFactory::getConfiguration();
     $registry->set('volatile.operation_counter', 0);
     // Advance step counter
     $stepCounter = $registry->get('volatile.step_counter', 0);
     $registry->set('volatile.step_counter', ++$stepCounter);
     // Log step start number
     AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, '====== Starting Step number ' . $stepCounter . ' ======');
     $timer = AliceFactory::getTimer();
     $finished = false;
     $error = false;
     $breakFlag = false;
     // BREAKFLAG is optionally passed by domains to force-break current operation
     // Apply an infinite time limit if required
     if ($registry->get('akeeba.tuning.settimelimit', 0)) {
         if (function_exists('set_time_limit')) {
             set_time_limit(0);
         }
     }
     $this->array_cache = null;
     // Loop until time's up, we're done or an error occurred, or BREAKFLAG is set
     while ($timer->getTimeLeft() > 0 && !$finished && !$error && !$breakFlag) {
         // Reset the break flag
         $registry->set('volatile.breakflag', false);
         // Do we have to switch domains? This only happens if there is no active
         // domain, or the current domain has finished
         $have_to_switch = false;
         if ($this->class == '') {
             $have_to_switch = true;
         } else {
             $object = AliceFactory::getDomainObject($this->class);
             if (!is_object($object)) {
                 $have_to_switch = true;
             } else {
                 if (!in_array('getState', get_class_methods($object))) {
                     $have_to_switch = true;
                 } else {
                     if ($object->getState() == 'finished') {
                         $have_to_switch = true;
                     }
                 }
             }
         }
         // Switch domain if necessary
         if ($have_to_switch) {
             // TODO Check what's the most conservative value and use it
             if (!AliceFactory::getConfiguration()->get('akeeba.tuning.nobreak.domains', 0)) {
                 AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "Kettenrad :: BREAKING STEP BEFORE SWITCHING DOMAIN");
                 $registry->set('volatile.breakflag', true);
             }
             $object = null;
             // Free last domain
             if (empty($this->domain_chain)) {
                 // Aw, we're done! No more domains to run.
                 $this->setState('postrun');
                 AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "Kettenrad :: No more domains to process");
                 $this->array_cache = null;
                 //restore_error_handler();
                 return;
             }
             // Shift the next definition off the stack
             $this->array_cache = null;
             $new_definition = array_shift($this->domain_chain);
             if (array_key_exists('class', $new_definition)) {
                 $this->domain = $new_definition['domain'];
                 $this->class = $new_definition['class'];
                 // Get a working object
                 $object = AliceFactory::getDomainObject($this->class);
                 $object->setup($this->_parametersArray);
             } else {
                 AliceUtilLogger::WriteLog(_AE_LOG_WARNING, "Kettenrad :: No class defined trying to switch domains. The analysis will crash.");
                 $this->domain = null;
                 $this->class = null;
             }
         } else {
             if (!is_object($object)) {
                 $object = AliceFactory::getDomainObject($this->class);
             }
         }
         // Tick the object
         $result = $object->tick();
         // Propagate errors
         $this->propagateFromObject($object);
         // Advance operation counter
         $currentOperationNumber = $registry->get('volatile.operation_counter', 0);
         $currentOperationNumber++;
         $registry->set('volatile.operation_counter', $currentOperationNumber);
         // Process return array
         $this->setDomain($this->domain);
         $this->setStep($result['Step']);
         $this->setSubstep($result['Substep']);
         // Check for BREAKFLAG
         $breakFlag = $registry->get('volatile.breakflag', false);
         // Process errors
         $error = false;
         if ($this->getError()) {
             $error = true;
         }
         // Check if the backup procedure should finish now
         $finished = $error ? true : !$result['HasRun'];
         // Log operation end
         AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, '----- Finished operation ' . $currentOperationNumber . ' ------');
     }
     // while
     // Log the result
     if (!$error) {
         AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "Successful Smart algorithm on " . get_class($object));
     } else {
         AliceUtilLogger::WriteLog(_AE_LOG_ERROR, "Failed Smart algorithm on " . get_class($object));
     }
     // Log if we have to do more work or not
     if (!is_object($object)) {
         AliceUtilLogger::WriteLog(_AE_LOG_WARNING, "Kettenrad :: Empty object found when processing domain '" . $this->domain . "'. This should never happen.");
     } else {
         if ($object->getState() == 'running') {
             AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "Kettenrad :: More work required in domain '" . $this->domain . "'");
             // We need to set the break flag for the part processing to not batch successive steps
             $registry->set('volatile.breakflag', true);
         } elseif ($object->getState() == 'finished') {
             AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, "Kettenrad :: Domain '" . $this->domain . "' has finished.");
             $registry->set('volatile.breakflag', false);
         }
     }
     // Log step end
     AliceUtilLogger::WriteLog(_AE_LOG_DEBUG, '====== Finished Step number ' . $stepCounter . ' ======');
     if (!$registry->get('akeeba.tuning.nobreak.domains', 0)) {
         // Force break between steps
         $registry->set('volatile.breakflag', true);
     }
     //restore_error_handler();
 }