-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Labels
enhancementNew feature or requestNew feature or requestgitautoGitAuto label to trigger the app in a issue.GitAuto label to trigger the app in a issue.good first issueGood for newcomersGood for newcomershacktoberfestParticipation in the Hacktoberfest eventParticipation in the Hacktoberfest eventhelp wantedExtra attention is neededExtra attention is needed📝 documentationTasks related to writing or updating documentationTasks related to writing or updating documentation🕓 medium effortA task that can be completed in a few hoursA task that can be completed in a few hours🛠 WIPWork in progressWork in progress🧪 testsTasks related to testingTasks related to testing
Description
Description
Add a class that handles open/half-open/close state for a simple CircuitBreaker.
This class depends upon #84 to manage state
- The settings/options should be configured by the constructor or via custom method (
failureThreshold,resetTimeout) MemoryCache([FEATURE] AddMemoryCacheclass #84) should be a constructor dependency
Tech notes
Simple example
class CircuitBreaker
{
private $state = 'closed';
private $failureThreshold = 5;
private $resetTimeout = 120;
private $failureCount = 0;
private $lastFailureTime = null;
private $memoryCache;
public function __construct()
{
$this->memoryCache = new MemoryCache();
$this->loadState();
}
public function __destruct()
{
$this->saveState();
}
private function saveState()
{
$state = array(
"state" => $this->state,
"failureCount" => $this->failureCount,
"lastFailureTime" => $this->lastFailureTime
);
$this->memoryCache->writeJsonInMemory($state);
}
private function loadState()
{
$state = $this->memoryCache->readJsonInMemory();
if (!isset($state["state"]) || !isset($state["failureCount"]) || !isset($state["lastFailureTime"])) {
return;
}
$this->state = $state["state"];
$this->failureCount = $state["failureCount"];
$this->lastFailureTime = $state["lastFailureTime"];
}
public function execute(callable $operation)
{
if ($this->state === 'open' && $this->isTimeoutReached()) {
$this->state = 'half-open';
}
if ($this->state === 'closed' || $this->state === 'half-open') {
try {
$result = $operation();
$this->reset();
return $result;
} catch (\Exception $e) {
$this->handleFailure();
throw $e;
} finally {
$this->saveState();
}
}
throw new CircuitBreakerOpenException("Circuit breaker is open until " . date('Y-m-d H:i:s', $this->lastFailureTime + $this->resetTimeout) . " (in " . ($this->lastFailureTime + $this->resetTimeout - time()) . " seconds)");
}
private function handleFailure()
{
$this->failureCount++;
$this->lastFailureTime = time();
if ($this->failureCount >= $this->failureThreshold) {
$this->state = 'open';
}
}
private function isTimeoutReached()
{
return time() - $this->lastFailureTime >= $this->resetTimeout;
}
private function reset()
{
$this->failureCount = 0;
$this->lastFailureTime = null;
$this->state = 'closed';
}
}
class CircuitBreakerOpenException extends \Exception
{
}Additional information
gitauto-ai
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestgitautoGitAuto label to trigger the app in a issue.GitAuto label to trigger the app in a issue.good first issueGood for newcomersGood for newcomershacktoberfestParticipation in the Hacktoberfest eventParticipation in the Hacktoberfest eventhelp wantedExtra attention is neededExtra attention is needed📝 documentationTasks related to writing or updating documentationTasks related to writing or updating documentation🕓 medium effortA task that can be completed in a few hoursA task that can be completed in a few hours🛠 WIPWork in progressWork in progress🧪 testsTasks related to testingTasks related to testing