Completed
Push — master ( b2dfe1...1412d2 )
by Sam
02:32
created

InstanceStateManager   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 121
Duplicated Lines 25.62 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

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

6 Methods

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