Completed
Push — master ( 07f159...bb7259 )
by Sam
03:38
created

InstanceStateManager   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 138
Duplicated Lines 21.74 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 93.02%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 10
c 5
b 0
f 0
lcom 1
cbo 7
dl 30
loc 138
ccs 40
cts 43
cp 0.9302
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 2
A onInstanceStatusCollectionRequest() 0 4 1
A getSubscribedEvents() 0 9 1
A getInstanceState() 0 4 1
A onInstanceReachable() 15 15 2
A onInstanceUnreachable() 15 15 1
A onInstanceMaybeReachable() 0 18 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Jalle19\StatusManager\Manager;
4
5
use Jalle19\StatusManager\Configuration\Configuration;
6
use Jalle19\StatusManager\Configuration\Instance;
7
use Jalle19\StatusManager\Event\Events;
8
use Jalle19\StatusManager\Event\InstanceStateEvent;
9
use Jalle19\StatusManager\Event\InstanceStatusCollectionRequestEvent;
10
use Jalle19\StatusManager\Instance\InstanceState;
11
use Psr\Log\LoggerInterface;
12
use Symfony\Component\EventDispatcher\EventDispatcher;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
15
/**
16
 * Keeps track of the reachability for all configures instances.
17
 *
18
 * @package   Jalle19\StatusManager\Manager
19
 * @copyright Copyright &copy; Sam Stenvall 2016-
20
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
21
 */
22
class InstanceStateManager extends AbstractManager implements EventSubscriberInterface
23
{
24
25
	/**
26
	 * The number of cycles to wait until retrying an unreachable instance
27
	 */
28
	const UNREACHABLE_CYCLES_UNTIL_RETRY = 10;
29
30
	/**
31
	 * @var \SplObjectStorage the instances to connect to and their individual state
32
	 */
33
	private $_instances;
34
35
36
	/**
37
	 * InstanceStateManager constructor.
38
	 *
39
	 * @param Configuration   $configuration
40
	 * @param LoggerInterface $logger
41
	 * @param EventDispatcher $eventDispatcher
42
	 */
43 2
	public function __construct(Configuration $configuration, LoggerInterface $logger, EventDispatcher $eventDispatcher)
44
	{
45 2
		parent::__construct($configuration, $logger, $eventDispatcher);
46
47 2
		$this->_instances = new \SplObjectStorage();
48
49
		// Attach a state to each instance
50 2
		foreach ($configuration->getInstances() as $instance)
51 2
			$this->_instances->attach($instance, new InstanceState());
52 2
	}
53
54
55
	/**
56
	 * @inheritdoc
57
	 */
58 2
	public static function getSubscribedEvents()
59
	{
60
		return [
61 2
			Events::INSTANCE_STATUS_COLLECTION_REQUEST => 'onInstanceStatusCollectionRequest',
62 2
			Events::INSTANCE_STATE_REACHABLE           => 'onInstanceReachable',
63 2
			Events::INSTANCE_STATE_UNREACHABLE         => 'onInstanceUnreachable',
64 2
			Events::INSTANCE_STATE_MAYBE_REACHABLE     => 'onInstanceMaybeReachable',
65
		];
66
	}
67
68
69
	/**
70
	 * Handler for the INSTANCE_STATUS_COLLECTION_EVENT event
71
	 *
72
	 * @param InstanceStatusCollectionRequestEvent $event
73
	 */
74
	public function onInstanceStatusCollectionRequest(InstanceStatusCollectionRequestEvent $event)
75
	{
76
		$event->setInstanceCollection($this->_instances);
77
	}
78
79
80
	/**
81
	 * Called when an instance was tried and reachable
82
	 *
83
	 * @param InstanceStateEvent $event
84
	 */
85 1 View Code Duplication
	public function onInstanceReachable(InstanceStateEvent $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
	{
87 1
		$instance      = $event->getInstance();
88 1
		$instanceState = $this->getInstanceState($instance);
89
90
		// Update reachability state now that we know the instance is reachable
91 1
		if ($instanceState->getReachability() === InstanceState::MAYBE_REACHABLE)
92
		{
93 1
			$this->logger->notice('Instance {instanceName} is now reachable, will start polling for updates', [
94 1
				'instanceName' => $instance->getName(),
95
			]);
96
97 1
			$instanceState->setReachability(InstanceState::REACHABLE);
98
		}
99 1
	}
100
101
102
	/**
103
	 * Called when an instance was tried and wasn't reachable
104
	 *
105
	 * @param InstanceStateEvent $event
106
	 */
107 1 View Code Duplication
	public function onInstanceUnreachable(InstanceStateEvent $event)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
	{
109 1
		$instance      = $event->getInstance();
110 1
		$instanceState = $this->getInstanceState($instance);
111
112
		// Mark the instance as unreachable
113 1
		$message = 'Instance {instanceName} not reachable, will wait for {cycles} cycles before retrying';
114
115 1
		$this->logger->warning($message, [
116 1
			'instanceName' => $instance->getName(),
117 1
			'cycles'       => self::UNREACHABLE_CYCLES_UNTIL_RETRY,
118
		]);
119
120 1
		$instanceState->setReachability(InstanceState::UNREACHABLE);
121 1
	}
122
123
124
	/**
125
	 * Called when a previously unreachable instance was left untried for the current tick
126
	 *
127
	 * @param InstanceStateEvent $event
128
	 */
129 1
	public function onInstanceMaybeReachable(InstanceStateEvent $event)
130
	{
131 1
		$instance      = $event->getInstance();
132 1
		$instanceState = $this->getInstanceState($instance);
133
134
		// Wait for some cycles and then mark unreachable instances as maybe reachable
135 1
		if ($instanceState->getRetryCount() === self::UNREACHABLE_CYCLES_UNTIL_RETRY - 1)
136
		{
137 1
			$instanceState->setReachability(InstanceState::MAYBE_REACHABLE);
138 1
			$instanceState->resetRetryCount();
139
140 1
			$this->logger->info('Retrying instance {instanceName} during next cycle', [
141 1
				'instanceName' => $instance->getName(),
142
			]);
143
		}
144
		else
145 1
			$instanceState->incrementRetryCount();
146 1
	}
147
148
149
	/**
150
	 * @param Instance $instance
151
	 *
152
	 * @return InstanceState
153
	 */
154 1
	public function getInstanceState(Instance $instance)
155
	{
156 1
		return $this->_instances[$instance];
157
	}
158
159
}
160