Completed
Push — master ( 132c41...627059 )
by Sam
02:29
created

InstanceStateManager   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 135
Duplicated Lines 22.96 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
c 1
b 0
f 0
lcom 1
cbo 4
dl 31
loc 135
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A onInstanceReachable() 16 16 2
A onInstanceUnreachable() 15 15 1
A onInstanceMaybeReachable() 0 18 2
A getInstances() 0 4 1
A isReachable() 0 4 1
A getInstanceState() 0 4 1

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;
4
5
use Jalle19\StatusManager\Event\InstanceStateEvent;
6
use Psr\Log\LoggerInterface;
7
8
/**
9
 * Keeps track of the reachability for all configures instances.
10
 *
11
 * @package   Jalle19\StatusManager
12
 * @copyright Copyright &copy; Sam Stenvall 2016-
13
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
14
 */
15
class InstanceStateManager
16
{
17
18
	/**
19
	 * The number of cycles to wait until retrying an unreachable instance
20
	 */
21
	const UNREACHABLE_CYCLES_UNTIL_RETRY = 10;
22
23
	/**
24
	 * @var LoggerInterface
25
	 */
26
	private $_logger;
27
28
	/**
29
	 * @var \SplObjectStorage the instances to connect to and their individual state
30
	 */
31
	private $_instances;
32
33
34
	/**
35
	 * @param LoggerInterface $logger
36
	 * @param Instance[]      $instances
37
	 */
38
	public function __construct(LoggerInterface $logger, array $instances)
39
	{
40
		$this->_logger    = $logger;
41
		$this->_instances = new \SplObjectStorage();
42
43
		// Attach a state to each instance
44
		foreach ($instances as $instance)
45
			$this->_instances->attach($instance, new InstanceState());
46
	}
47
48
49
	/**
50
	 * Called when an instance was tried and reachable
51
	 *
52
	 * @param InstanceStateEvent $event
53
	 */
54 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...
55
	{
56
		$instance      = $event->getInstance();
57
		$instanceState = $this->getInstanceState($instance);
58
59
		// Update reachability state now that we know the instance is reachable
60
		if ($instanceState->getReachability() === InstanceState::MAYBE_REACHABLE)
61
		{
62
			$this->_logger->info('Instance {instanceName} is now reachable, will start polling for updates',
63
				[
64
					'instanceName' => $instance->getName(),
65
				]);
66
67
			$instanceState->setReachability(InstanceState::REACHABLE);
68
		}
69
	}
70
71
72
	/**
73
	 * Called when an instance was tried and wasn't reachable
74
	 *
75
	 * @param InstanceStateEvent $event
76
	 */
77 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...
78
	{
79
		$instance      = $event->getInstance();
80
		$instanceState = $this->getInstanceState($instance);
81
82
		// Mark the instance as unreachable
83
		$message = 'Instance {instanceName} not reachable, will wait for {cycles} cycles before retrying';
84
85
		$this->_logger->alert($message, [
86
			'instanceName' => $instance->getName(),
87
			'cycles'       => self::UNREACHABLE_CYCLES_UNTIL_RETRY,
88
		]);
89
90
		$instanceState->setReachability(InstanceState::UNREACHABLE);
91
	}
92
93
94
	/**
95
	 * Called when a previously unreachable instance was left untried for the current tick
96
	 *
97
	 * @param InstanceStateEvent $event
98
	 */
99
	public function onInstanceMaybeReachable(InstanceStateEvent $event)
100
	{
101
		$instance      = $event->getInstance();
102
		$instanceState = $this->getInstanceState($instance);
103
104
		// Wait for some cycles and then mark unreachable instances as maybe reachable
105
		if ($instanceState->getRetryCount() === self::UNREACHABLE_CYCLES_UNTIL_RETRY - 1)
106
		{
107
			$instanceState->setReachability(InstanceState::MAYBE_REACHABLE);
108
			$instanceState->resetRetryCount();
109
110
			$this->_logger->info('Retrying instance {instanceName} during next cycle', [
111
				'instanceName' => $instance->getName(),
112
			]);
113
		}
114
		else
115
			$instanceState->incrementRetryCount();
116
	}
117
118
119
	/**
120
	 * @return \SplObjectStorage
121
	 */
122
	public function getInstances()
123
	{
124
		return $this->_instances;
125
	}
126
127
128
	/**
129
	 * @param Instance $instance
130
	 *
131
	 * @return bool
132
	 */
133
	public function isReachable(Instance $instance)
134
	{
135
		return $this->getInstanceState($instance)->isReachable();
136
	}
137
138
139
	/**
140
	 * @param Instance $instance
141
	 *
142
	 * @return InstanceState
143
	 */
144
	private function getInstanceState(Instance $instance)
145
	{
146
		return $this->_instances[$instance];
147
	}
148
149
}
150