Skip to content

Commit

Permalink
Merge pull request #7 from leocarmo/v3.0.0
Browse files Browse the repository at this point in the history
V3.0.0
  • Loading branch information
leocarmo authored Dec 21, 2020
2 parents 886788b + 2b79724 commit 7f76db9
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 85 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
/.vagrant
/vendor
composer.lock
.env
.env
*.cache
7 changes: 3 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
language: php

php:
- '7.1'
- '7.2'
- '7.3'
- '7.4'
- '8.0'

env:
- REDIS_HOST=0.0.0.0 REDIS_PORT=6379
- REDIS_HOST=0.0.0.0 REDIS_PORT=6379 XDEBUG_MODE=coverage

services:
- docker
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
test:
@echo "---- Running tests ----"
@./vendor/bin/phpunit
@./vendor/bin/phpunit --testdox tests

test-coverage:
@echo "---- Running tests with coverage report ----"
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
}
},
"require": {
"php": ">=7.1",
"php": "^7.4 || ^8.0",
"ext-redis": "*"
},
"require-dev": {
"phpunit/phpunit": "~7.0",
"phpunit/php-code-coverage": "^6.1",
"symfony/var-dumper": "^4.3"
"phpunit/phpunit": "^9",
"phpunit/php-code-coverage": "^9.2",
"symfony/var-dumper": "^5.2"
}
}
12 changes: 9 additions & 3 deletions examples/CircuitBreakerRedisAdapterExample.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
require '../vendor/autoload.php';
require_once __DIR__ . '/../vendor/autoload.php';

use LeoCarmo\CircuitBreaker\CircuitBreaker;

Expand Down Expand Up @@ -32,10 +32,16 @@
}

// Usage example for success and failure
function myService() {
if (rand(1, 100) >= 50) {
throw new RuntimeException('Something got wrong!');
}
}

try {
\Service::execute();
myService();
CircuitBreaker::success('my-service');
} catch (\ServiceException $e) {
} catch (RuntimeException $e) {
// If an error occurred, it must be recorded as failure.
CircuitBreaker::failure('my-service');
die($e->getMessage());
Expand Down
35 changes: 19 additions & 16 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Application Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-html" target="./.ci/codeCoverage/" lowUpperBound="35" highLowerBound="70"/>
<log type="coverage-clover" target="./.ci/codeCoverage/codeCoverage.xml"/>
</logging>
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
<report>
<clover outputFile="./.ci/codeCoverage/codeCoverage.xml"/>
<html outputDirectory="./.ci/codeCoverage/" lowUpperBound="35" highLowerBound="70"/>
</report>
</coverage>
<testsuites>
<testsuite name="Application Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
<logging/>
</phpunit>
14 changes: 7 additions & 7 deletions src/Adapters/AdapterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
interface AdapterInterface
{

public function isOpen(string $service) : bool;
public function isOpen(string $service): bool;

public function reachRateLimit(string $service) : bool;
public function reachRateLimit(string $service): bool;

public function setOpenCircuit(string $service) : void;
public function setOpenCircuit(string $service): void;

public function setHalfOpenCircuit(string $service) : void;
public function setHalfOpenCircuit(string $service): void;

public function isHalfOpen(string $service) : bool;
public function isHalfOpen(string $service): bool;

public function incrementFailure(string $service) : bool;
public function incrementFailure(string $service): bool;

public function setSuccess(string $service) : bool;
public function setSuccess(string $service): void;

}
58 changes: 31 additions & 27 deletions src/Adapters/RedisAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,66 @@

namespace LeoCarmo\CircuitBreaker\Adapters;

use Redis;
use LeoCarmo\CircuitBreaker\CircuitBreaker;

class RedisAdapter implements AdapterInterface
{

/**
* @var \Redis
* @var Redis
*/
protected $redis;
protected Redis $redis;

/**
* @var string
*/
protected $redisNamespace;
protected string $redisNamespace;

/**
* @var array
*/
protected $cachedService = [];
protected array $cachedService = [];

/**
* Set settings for start circuit service
*
* @param \Redis $redis
* @param Redis $redis
* @param string $redisNamespace
*/
public function __construct(\Redis $redis, string $redisNamespace)
public function __construct(Redis $redis, string $redisNamespace)
{
$this->redis = $redis;
$this->redisNamespace = $redisNamespace;
}

/**
* @param string $service
* @return bool|string
* @return bool
*/
public function isOpen(string $service) : bool
public function isOpen(string $service): bool
{
return $this->redis->get($this->makeNamespace($service) . ':open');
return (bool) $this->redis->get($this->makeNamespace($service) . ':open');
}

/**
* @param string $service
* @return bool
*/
public function reachRateLimit(string $service) : bool
public function reachRateLimit(string $service): bool
{
$failures = $this->redis->get(
$failures = (int) $this->redis->get(
$this->makeNamespace($service) . ':failures'
);

return $failures && $failures >= CircuitBreaker::getServiceSetting($service, 'failureRateThreshold');
return ($failures >= CircuitBreaker::getServiceSetting($service, 'failureRateThreshold'));
}

/**
* @param string $service
* @return bool|string
*/
public function isHalfOpen(string $service) : bool
public function isHalfOpen(string $service): bool
{
return (bool) $this->redis->get($this->makeNamespace($service) . ':half_open');
}
Expand All @@ -71,33 +72,36 @@ public function isHalfOpen(string $service) : bool
*/
public function incrementFailure(string $service) : bool
{
$serviceFailures = self::makeNamespace($service) . ':failures';
$serviceName = $this->makeNamespace($service) . ':failures';

if (! $this->redis->get($serviceFailures)) {
if (! $this->redis->get($serviceName)) {
$this->redis->multi();
$this->redis->incr($serviceFailures);
$this->redis->expire($serviceFailures, CircuitBreaker::getServiceSetting($service, 'timeWindow'));
return (bool) $this->redis->exec()[0] ?? false;
$this->redis->incr($serviceName);
$this->redis->expire($serviceName, CircuitBreaker::getServiceSetting($service, 'timeWindow'));
return (bool) ($this->redis->exec()[0] ?? false);
}

return (bool) $this->redis->incr($serviceFailures);
return (bool) $this->redis->incr($serviceName);
}

/**
* @param string $service
* @return bool
*/
public function setSuccess(string $service) : bool
public function setSuccess(string $service): void
{
return $this->redis->del($this->makeNamespace($service) . ':open')
&& $this->redis->del($this->makeNamespace($service) . ':failures')
&& $this->redis->del($this->makeNamespace($service) . ':half_open');
$serviceName = $this->makeNamespace($service);

$this->redis->multi();
$this->redis->del($serviceName . ':open');
$this->redis->del($serviceName . ':failures');
$this->redis->del($serviceName . ':half_open');
$this->redis->exec();
}

/**
* @param string $service
*/
public function setOpenCircuit(string $service) : void
public function setOpenCircuit(string $service): void
{
$this->redis->set(
$this->makeNamespace($service) . ':open',
Expand All @@ -109,7 +113,7 @@ public function setOpenCircuit(string $service) : void
/**
* @param string $service
*/
public function setHalfOpenCircuit(string $service) : void
public function setHalfOpenCircuit(string $service): void
{
$this->redis->set(
$this->makeNamespace($service) . ':half_open',
Expand All @@ -123,7 +127,7 @@ public function setHalfOpenCircuit(string $service) : void
* @param string $service
* @return string
*/
protected function makeNamespace(string $service)
protected function makeNamespace(string $service): string
{
if (isset($this->cachedService[$service])) {
return $this->cachedService[$service];
Expand Down
Loading

0 comments on commit 7f76db9

Please sign in to comment.