Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Add CircuitBreaker class #85

Open
guibranco opened this issue Mar 19, 2024 · 1 comment · May be fixed by #239
Open

[FEATURE] Add CircuitBreaker class #85

guibranco opened this issue Mar 19, 2024 · 1 comment · May be fixed by #239
Labels
📝 documentation Tasks related to writing or updating documentation enhancement New feature or request gitauto GitAuto label to trigger the app in a issue. good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event help wanted Extra attention is needed 🕓 medium effort A task that can be completed in a few hours 🧪 tests Tasks related to testing 🛠 WIP Work in progress

Comments

@guibranco
Copy link
Owner

guibranco commented Mar 19, 2024

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] Add MemoryCache class #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

⚠️ 🚨 Add documentation and tests

@guibranco guibranco added the enhancement New feature or request label Mar 19, 2024
@guibranco guibranco added the 📝 documentation Tasks related to writing or updating documentation label Jun 8, 2024
@guibranco guibranco added help wanted Extra attention is needed good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event labels Jul 4, 2024
@guibranco guibranco changed the title [FEATURE] Add CircuitBreaker class [FEATURE] Add CircuitBreaker class Jul 4, 2024
@guibranco guibranco added 🧪 tests Tasks related to testing 🕓 medium effort A task that can be completed in a few hours labels Oct 21, 2024
@gitauto-ai gitauto-ai bot added the gitauto GitAuto label to trigger the app in a issue. label Oct 22, 2024
Copy link
Contributor

gitauto-ai bot commented Oct 22, 2024

Hey, I'm a bit lost here! Not sure which file I should be fixing. Could you give me a bit more to go on? Maybe add some details to the issue or drop a comment with some extra hints? Thanks!

Have feedback or need help?
Feel free to email [email protected].

@gitauto-ai gitauto-ai bot linked a pull request Oct 22, 2024 that will close this issue
@gstraccini gstraccini bot added the 🛠 WIP Work in progress label Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📝 documentation Tasks related to writing or updating documentation enhancement New feature or request gitauto GitAuto label to trigger the app in a issue. good first issue Good for newcomers hacktoberfest Participation in the Hacktoberfest event help wanted Extra attention is needed 🕓 medium effort A task that can be completed in a few hours 🧪 tests Tasks related to testing 🛠 WIP Work in progress
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant