From a9d4837213042d38d8ac1cad0bbedc7566a19c17 Mon Sep 17 00:00:00 2001 From: Ludovic Gonthier Date: Thu, 16 Mar 2017 18:29:14 +0100 Subject: [PATCH] feat(cb): add trait for ease of cb use --- Service/CircuitBreakerService.php | 3 + Tests/Traits/CircuitBreakerAwareTraitTest.php | 79 +++++++++++++++++++ Traits/CircuitBreakerAwareTrait.php | 65 +++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 Tests/Traits/CircuitBreakerAwareTraitTest.php create mode 100644 Traits/CircuitBreakerAwareTrait.php diff --git a/Service/CircuitBreakerService.php b/Service/CircuitBreakerService.php index 1ef3fe0..ccf8b70 100644 --- a/Service/CircuitBreakerService.php +++ b/Service/CircuitBreakerService.php @@ -14,6 +14,9 @@ class CircuitBreakerService const CLOSED = 'closed'; const HALFOPEN = 'half-open'; + const STATUS_UP = true; + const STATUS_DOWN = false; + /** * @var AbstractAdapter */ diff --git a/Tests/Traits/CircuitBreakerAwareTraitTest.php b/Tests/Traits/CircuitBreakerAwareTraitTest.php new file mode 100644 index 0000000..72a3335 --- /dev/null +++ b/Tests/Traits/CircuitBreakerAwareTraitTest.php @@ -0,0 +1,79 @@ +eventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->circuitBreaker = $this->createMock(CircuitBreakerService::class); + } + + + public function testSetCircuitBreaker() + { + $trait = $this->getMockForTrait(CircuitBreakerAwareTrait::class); + + $trait->setCircuitBreaker($this->circuitBreaker); + + $this->assertSame( + $this->circuitBreaker, + \PHPUnit_Framework_Assert::readAttribute($trait, 'circuitBreaker') + ); + } + + public function testSetEventDispatcher() + { + $trait = $this->getMockForTrait(CircuitBreakerAwareTrait::class); + + $trait->setEventDispatcher($this->eventDispatcher); + + $this->assertSame( + $this->eventDispatcher, + \PHPUnit_Framework_Assert::readAttribute($trait, 'eventDispatcher') + ); + } + + public function testNotifyServiceIsDown() + { + $trait = $this->getMockForTrait(CircuitBreakerAwareTrait::class); + $trait->setEventDispatcher($this->eventDispatcher); + + $this->eventDispatcher + ->expects($this->once()) + ->method('dispatch') + ->with('circuit.breaker', $this->callback(function ($event) { + return $event instanceof CircuitBreakerEvent + && $event->getKey() === 'test_service' + && $event->getStatus() === CircuitBreakerService::STATUS_DOWN; + })); + + $trait->notifyServiceIsDown('test_service'); + } + + public function testNotifyServiceIsUp() + { + $trait = $this->getMockForTrait(CircuitBreakerAwareTrait::class); + $trait->setEventDispatcher($this->eventDispatcher); + + $this->eventDispatcher + ->expects($this->once()) + ->method('dispatch') + ->with('circuit.breaker', $this->callback(function ($event) { + return $event instanceof CircuitBreakerEvent + && $event->getKey() === 'test_service' + && $event->getStatus() === CircuitBreakerService::STATUS_UP; + })); + + $trait->notifyServiceIsUp('test_service'); + } +} diff --git a/Traits/CircuitBreakerAwareTrait.php b/Traits/CircuitBreakerAwareTrait.php new file mode 100644 index 0000000..e5d43e6 --- /dev/null +++ b/Traits/CircuitBreakerAwareTrait.php @@ -0,0 +1,65 @@ +circuitBreaker = $circuitBreaker; + } + + /** + * @param EventDispatcherInterface $eventDispatcher + */ + public function setEventDispatcher(EventDispatcherInterface $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + + + /** + * Send an event to notify the circuit breaker that a given service is down + * + * @param string $serviceName The service which is down + */ + public function notifyServiceIsDown(string $serviceName) + { + $this->eventDispatcher->dispatch( + 'circuit.breaker', + new CircuitBreakerEvent($serviceName, CircuitBreakerService::STATUS_DOWN) + ); + } + + /** + * Send an event to notify the circuit breaker that a given service is up + * + * @param string $serviceName The service which is up + */ + public function notifyServiceIsUp(string $serviceName) + { + $this->eventDispatcher->dispatch( + 'circuit.breaker', + new CircuitBreakerEvent($serviceName, CircuitBreakerService::STATUS_UP) + ); + } +}