Ejemplo n.º 1
0
 /**
  * @url GET stats/performance/conjuncts
  * @param string $groupBy
  * @param int $from
  * @param int $to
  */
 public function conjPerfStats($groupBy = 'conjuncts', $from = 0, $to = 10)
 {
     try {
         if (Config::get('productionEnv')) {
             throw new Exception("Performance tests are not allowed in production environment", 403);
         }
         $performanceArr = array();
         // run all conjuncts (from - to)
         for ($i = $from; $i <= $to; $i++) {
             $conj = RuleEngine::getConjunct('conj_' . $i);
             $startTimeStamp = microtime(true);
             // true means get as float instead of string
             RuleEngine::checkConjunct('conj_' . $i, false);
             $endTimeStamp = microtime(true);
             $performanceArr['conj_' . $i] = array('id' => 'conj_' . $i, 'start' => $startTimeStamp, 'end' => $endTimeStamp, 'duration' => $endTimeStamp - $startTimeStamp, 'invariantRules' => implode(';', $conj['invariantRuleNames']), 'signalRules' => implode(';', $conj['signalRuleNames']));
         }
         switch ($groupBy) {
             case 'conjuncts':
                 return array_values($performanceArr);
                 break;
             case 'rules':
                 $ruleArr = array();
                 foreach (RuleEngine::getAllRules() as $rule) {
                     $duration = 0;
                     foreach ($rule['conjunctIds'] as $conj) {
                         $duration += $performanceArr[$conj]['duration'];
                     }
                     $ruleArr[] = array('ruleName' => $rule['name'], 'duration' => $duration, 'conjuncts' => implode(';', $rule['conjunctIds']));
                 }
                 return $ruleArr;
                 break;
             case 'relations':
                 $relArr = array();
                 foreach (Relation::getAllRelations() as $sig => $rel) {
                     $duration = 0;
                     $conjuncts = array_merge($rel['affectedInvConjunctIds'], $rel['affectedSigConjunctIds']);
                     foreach ($conjuncts as $conj) {
                         $duration += $performanceArr[$conj]['duration'];
                     }
                     $relArr[] = array('relationSignature' => $sig, 'duration' => $duration, 'conjuncts' => implode(';', $conjuncts));
                 }
                 return $relArr;
                 break;
             default:
                 throw new Exception("Unknown groupBy argument", 500);
                 break;
         }
     } catch (Exception $e) {
         throw new RestException($e->getCode(), $e->getMessage());
     }
 }
Ejemplo n.º 2
0
 public static function checkConjunct($conjunctId, $cacheConjuncts = true)
 {
     Notifications::addLog("Checking conjunct '" . $conjunctId . "' cache:" . var_export($cacheConjuncts, true), 'RuleEngine');
     try {
         // If conjunct is already evaluated and conjunctCach may be used -> return violations
         if (array_key_exists($conjunctId, self::$conjunctViolations) && $cacheConjuncts) {
             Notifications::addLog("Conjunct is already evaluated, getting violations from cache", 'RuleEngine');
             return self::$conjunctViolations[$conjunctId];
             // Otherwise evaluate conjunct, cache and return violations
         } else {
             $db = Database::singleton();
             $violations = array();
             // Evaluate conjunct
             $conjunct = RuleEngine::getConjunct($conjunctId);
             $violations = (array) $db->Exe($conjunct['violationsSQL']);
             // Cache violations
             if ($cacheConjuncts) {
                 self::$conjunctViolations[$conjunctId] = $violations;
             }
             if (count($violations) == 0) {
                 Notifications::addLog("Conjunct '" . $conjunctId . "' holds", 'RuleEngine');
                 // Remove "old" conjunct violations from database
                 $query = "DELETE FROM `__all_signals__` WHERE `conjId` = '{$conjunctId}'";
                 $db->Exe($query);
             } elseif ($cacheConjuncts) {
                 Notifications::addLog("Conjunct '" . $conjunctId . "' broken, caching violations in database", 'RuleEngine');
                 // Remove "old" conjunct violations from database
                 $query = "DELETE FROM `__all_signals__` WHERE `conjId` = '{$conjunctId}'";
                 $db->Exe($query);
                 // Add new conjunct violation to database table __all_signals__
                 $query = "INSERT IGNORE INTO `__all_signals__` (`conjId`, `src`, `tgt`) VALUES ";
                 foreach ($violations as $violation) {
                     $values[] = "('" . $conjunctId . "', '" . $violation['src'] . "', '" . $violation['tgt'] . "')";
                 }
                 $query .= implode(',', $values);
                 $db->Exe($query);
             } else {
                 Notifications::addLog("Conjunct '" . $conjunctId . "' broken", 'RuleEngine');
             }
             return $violations;
         }
     } catch (Exception $e) {
         Notifications::addError("While checking conjunct '" . $conjunctId . "': " . $e->getMessage());
     }
 }
Ejemplo n.º 3
0
 public static function run($allRules = false)
 {
     $database = Database::singleton();
     Notifications::addLog('------------------------- EXEC ENGINE STARTED -------------------------', 'ExecEngine');
     // Load the execEngine functions (security hazard :P)
     $files = getDirectoryList(__DIR__ . '/functions');
     foreach ($files as $file) {
         if (substr($file, -3) !== 'php') {
             continue;
         }
         require_once __DIR__ . '/functions/' . $file;
         Notifications::addLog('Included file: ' . __DIR__ . '/functions/' . $file, 'ExecEngine');
     }
     self::$roleName = Config::get('execEngineRoleName', 'execEngine');
     $role = Role::getRoleByName(self::$roleName);
     $maxRunCount = Config::get('maxRunCount', 'execEngine');
     self::$runCount = 0;
     self::$autoRerun = Config::get('autoRerun', 'execEngine');
     if ($role) {
         // Get all rules that are maintained by the ExecEngine
         while (self::$doRun) {
             self::$doRun = false;
             self::$runCount++;
             if (self::$runCount > $maxRunCount) {
                 throw new Exception('Maximum reruns exceeded for ExecEngine (rules with violations:' . implode(', ', $rulesThatHaveViolations) . ')', 500);
             }
             Notifications::addLog("ExecEngine run #" . self::$runCount . " (auto rerun: " . var_export(self::$autoRerun, true) . ") for role '" . $role->label . "'", 'ExecEngine');
             // Determine affected rules that must be checked by the exec engine
             $affectedConjuncts = (array) RuleEngine::getAffectedInvConjuncts($database->getAffectedConcepts(), $database->getAffectedRelations());
             $affectedConjuncts = array_merge($affectedConjuncts, (array) RuleEngine::getAffectedSigConjuncts($database->getAffectedConcepts(), $database->getAffectedRelations()));
             $affectedRules = array();
             foreach ($affectedConjuncts as $conjunctId) {
                 $conjunct = RuleEngine::getConjunct($conjunctId);
                 foreach ($conjunct['invariantRuleNames'] as $ruleName) {
                     $affectedRules[] = $ruleName;
                 }
                 foreach ($conjunct['signalRuleNames'] as $ruleName) {
                     $affectedRules[] = $ruleName;
                 }
             }
             // Check rules
             $rulesThatHaveViolations = array();
             foreach ($role->maintains() as $ruleName) {
                 if (!in_array($ruleName, $affectedRules) && !$allRules) {
                     continue;
                 }
                 // skip this rule
                 $rule = RuleEngine::getRule($ruleName);
                 $violations = RuleEngine::checkRule($rule, false);
                 if (count($violations)) {
                     $rulesThatHaveViolations[] = $rule['name'];
                     // Fix violations for every rule
                     ExecEngine::fixViolations($rule, $violations);
                     // Conjunct violations are not cached, because they are fixed by the ExecEngine
                     // If $autoRerun, set $doRun to true because violations have been fixed (this may fire other execEngine rules)
                     if (self::$autoRerun) {
                         self::$doRun = true;
                     }
                 }
             }
         }
     } else {
         Notifications::addInfo("ExecEngine extension included but role '" . self::$roleName . "' not found.");
     }
     Notifications::addLog('------------------------- END OF EXEC ENGINE -------------------------', 'ExecEngine');
 }