/** * Get the count of activities with a reason in a given state * * @param string $control * @param HistoryItemState $state * @return int */ public function countControl($control, HistoryItemState $state) { $cache_key = 'C:' . $control . ':' . $state->key(); if (array_key_exists($cache_key, $this->completion_cache)) { return $this->completion_cache[$cache_key]; } $count = 0; foreach ($this->history as $history_item) { /** @var WorkflowHistoryItem $history_item */ if ($history_item->getControl() == $control && $history_item->getState() == $state) { $count++; } } $this->completion_cache[$cache_key] = $count; return $count; }
public function apply(WorkflowHistory $history) { $item = $this->getHistoryItem($history, $this->getAttribute('scheduledEventId')); $item->setTimeStarted($this->timestamp); $item->setState(HistoryItemState::RUNNING()); $history->add($item); }
public function apply(WorkflowHistory $history) { $item = $this->getHistoryItem($history, $this->getAttribute('scheduledEventId')); $item->setTimeEnded($this->timestamp); $item->setState(HistoryItemState::CANCELLED()); $item->setErrorMessage('(Cancelled) ' . $this->getAttribute('details')); $history->add($item); }
public function apply(WorkflowHistory $history) { $item = $this->getHistoryItem($history, $this->getAttribute('scheduledEventId')); $item->setTimeEnded($this->timestamp); $item->setResult($this->getAttribute('result')); $item->setState(HistoryItemState::COMPLETED()); $history->add($item); }
/** * If the passed item is in a failed state, automatically flag this workflow as having a failed activity * * @param WorkflowHistoryItem $item */ protected function flagActivityFailure(WorkflowHistoryItem $item) { switch ($item->getState()) { case HistoryItemState::FAILED(): case HistoryItemState::TIMED_OUT(): $this->setActivityFailed(); $this->error_messages[] = $item->getErrorMessage(); default: return; } }
public function apply(WorkflowHistory $history) { $reason = $this->getAttribute('timeoutType'); if ($details = $this->getAttribute('details', null)) { $reason .= ' (' . $details . ')'; } $item = $this->getHistoryItem($history, $this->getAttribute('scheduledEventId')); $item->setTimeEnded($this->timestamp); $item->setState(HistoryItemState::TIMED_OUT()); $item->setErrorMessage('(Timeout) ' . $reason); $history->add($item); }
public function apply(WorkflowHistory $history) { $item = new WorkflowHistoryItem(); $item->setState(HistoryItemState::SCHEDULED()); $item->setTimeScheduled($this->timestamp); $item->setEventId($this->event_id); $item->setInput($this->getAttribute('input')); $item->setControl($this->getAttribute('control')); $item->setActivityName($this->getAttribute(['activityType', 'name'])); $item->setActivityVersion($this->getAttribute(['activityType', 'version'])); $history->add($item); }
public function testCounts() { $history = new WorkflowHistory(); $history->add($this->createHistoryItem('test-activity', '1', HistoryItemState::COMPLETED(), 'alpha')); $history->add($this->createHistoryItem('test-activity', '1', HistoryItemState::COMPLETED(), 'bravo')); $history->add($this->createHistoryItem('test-activity', '2', HistoryItemState::COMPLETED(), 'charlie')); $history->add($this->createHistoryItem('test-activity', '1', HistoryItemState::SCHEDULED(), 'delta')); $history->add($this->createHistoryItem('other-activity', '1', HistoryItemState::COMPLETED(), 'echo')); $history->add($this->createHistoryItem('other-activity', '1', HistoryItemState::RUNNING(), 'foxtrot')); $inspector = new HistoryInspector($history); $schema_test = TaskSchema::fromKey('test-activity/1'); $schema_other = TaskSchema::fromKey('other-activity/1'); $this->assertEquals(0, $inspector->countTask($schema_test, HistoryItemState::RUNNING())); $this->assertEquals(0, $inspector->countTask($schema_test, HistoryItemState::FAILED())); $this->assertEquals(2, $inspector->countTask($schema_test, HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countTask($schema_test, HistoryItemState::SCHEDULED())); $this->assertEquals(1, $inspector->countTask($schema_other, HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countTask($schema_other, HistoryItemState::RUNNING())); $this->assertEquals(0, $inspector->countTask($schema_other, HistoryItemState::SCHEDULED())); $this->assertEquals(0, $inspector->countTask($schema_other, HistoryItemState::FAILED())); $this->assertEquals(1, $inspector->countControl('alpha', HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countControl('bravo', HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countControl('charlie', HistoryItemState::COMPLETED())); $this->assertEquals(0, $inspector->countControl('delta', HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countControl('echo', HistoryItemState::COMPLETED())); $this->assertEquals(0, $inspector->countControl('foxtrot', HistoryItemState::COMPLETED())); $this->assertTrue($inspector->haveOpenActivities()); $alpha = new TaskSchema(); $alpha->setActivityName('test-activity')->setActivityVersion('1')->setControl('alpha'); $this->assertEquals(2, $inspector->countTask($alpha, HistoryItemState::COMPLETED())); $this->assertEquals(1, $inspector->countTask($alpha, HistoryItemState::SCHEDULED())); $omega = new TaskSchema(); $omega->setActivityName('test-activity')->setActivityVersion('10'); $this->assertEquals(0, $inspector->countTask($omega, HistoryItemState::COMPLETED())); $this->assertTrue($inspector->hasTaskBeenScheduled($alpha)); $this->assertFalse($inspector->hasTaskBeenScheduled($omega)); }
/** * Process the decision event, generating a decision response (included in the DecisionEvent) * * @param DecisionEvent $event */ public function processDecisionEvent(DecisionEvent $event) { $history = $event->getHistory(); $decision = $event->getDecision(); $tasks = $this->getWorkflow()->getTasks(); // Create a memory pool jailed to this execution $memory_pool = $this->getWorkflow()->getJailMemoryPool() ? JailedMemoryPool::jail($this->getMemoryPool(), ':' . $event->getExecutionId()) : $this->getMemoryPool(); // Check if we need to execute any task events /** @var WorkflowHistoryItem $history_item */ foreach ($history as $history_item) { $id = $history_item->getEventId(); if ($history_item->getState() == HistoryItemState::COMPLETED()) { if ($memory_pool->get('history:' . $id . ':completed') === null) { $this->runTaskDecider($history_item, $decision, $memory_pool); $memory_pool->set('history:' . $id . ':completed', 1); } } } // Check if we need to fail if ($this->getFailOnActivityFailure() && $history->hasActivityFailure() || $history->hasWorkflowFailed()) { $decision->setWorkflowResult(WorkflowResult::FAIL()); $decision->setReason(implode(", ", $history->getErrorMessages())); return; } // Check if we need to schedule $parser = new InputParser($history, $memory_pool); $scheduler = new Scheduler($history, $memory_pool); foreach ($tasks as $task) { if ($scheduler->canScheduleTask($task)) { $decision->scheduledTask($parser->compileTaskInput($task)); } } // Check if we need to complete if (count($decision->getScheduledTasks()) == 0 && !$scheduler->haveOpenActivities()) { $decision->setWorkflowResult(WorkflowResult::COMPLETE()); } }
/** * Check if this history item is a failure * * Includes failing, cancelling and timing out. * * @return bool */ public function isFailure() { switch ($this->state) { case HistoryItemState::CANCELLED(): case HistoryItemState::FAILED(): case HistoryItemState::TIMED_OUT(): return true; default: return false; } }
public function testActivityFail() { Conf::init(__DIR__ . '/../../../../config/'); $memory_pool = new RedisMemoryPool('decider-tests', 60, Conf::get('redis')); $decider = new Decider(); $decider->setWorkflow(new YamlWorkflow(__DIR__ . '/../Resources/TestSchema.yml')); $decider->setMemoryPool($memory_pool); // Workflow started - $event1 = new DecisionEvent(); $decider->processDecisionEvent($event1); $this->assertCount(1, $event1->getDecision()->getScheduledTasks()); $this->assertEquals(WorkflowResult::COMMAND(), $event1->getDecision()->getWorkflowResult()); $task = $event1->getDecision()->getScheduledTasks()[0]; $this->assertEquals('alpha', $task->getControl()); // Task 1 failed - $alpha = new WorkflowHistoryItem('1'); $alpha->setActivityName('test-activity')->setActivityVersion('1'); $alpha->setTimeScheduled(new \DateTime('2014-10-10 10:01:00')); $alpha->setTimeStarted(new \DateTime('2014-10-10 10:00:00')); $alpha->setTimeEnded(new \DateTime('2014-10-10 10:04:00')); $alpha->setState(HistoryItemState::FAILED()); $alpha->setErrorMessage('Test failure'); $alpha->setControl('alpha')->setInput('alpha')->setResult(">.<"); $event2 = new DecisionEvent(); $event2->getHistory()->add($alpha); $decider->processDecisionEvent($event2); $this->assertCount(0, $event2->getDecision()->getScheduledTasks()); $this->assertEquals(WorkflowResult::FAIL(), $event2->getDecision()->getWorkflowResult()); }
/** * Check if we meet all reason requirements * * @param array $requirements * @return bool */ protected function meetsControlRequirements(array $requirements) { foreach ($requirements as $control => $count) { if ($this->history_inspector->countControl($control, HistoryItemState::COMPLETED()) != $count) { return false; } } return true; }