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

StatusManager::requestInstances()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Jalle19\StatusManager\Manager;
4
5
use Jalle19\StatusManager\Configuration\Instance;
6
use Jalle19\StatusManager\Event\ConnectionSeenEvent;
7
use Jalle19\StatusManager\Event\Events;
8
use Jalle19\StatusManager\Event\InputSeenEvent;
9
use Jalle19\StatusManager\Event\InstanceCollectionEvent;
10
use Jalle19\StatusManager\Event\InstanceSeenEvent;
11
use Jalle19\StatusManager\Event\InstanceStateEvent;
12
use Jalle19\StatusManager\Event\InstanceStatusUpdatesEvent;
13
use Jalle19\StatusManager\Event\SubscriptionSeenEvent;
14
use Jalle19\StatusManager\Event\SubscriptionStateChangeEvent;
15
use Jalle19\StatusManager\Instance\InstanceStatus;
16
use Jalle19\StatusManager\Instance\InstanceStatusCollection;
17
use Jalle19\StatusManager\Subscription\StateChangeParser;
18
19
/**
20
 * Class StatusManager
21
 * @package   Jalle19\StatusManager\Manager
22
 * @copyright Copyright &copy; Sam Stenvall 2015-
23
 * @license   https://www.gnu.org/licenses/gpl.html The GNU General Public License v2.0
24
 */
25
class StatusManager extends AbstractManager
26
{
27
28
	/**
29
	 * Called right before the main loop is started
30
	 */
31
	public function onMainLoopStarted()
32
	{
33
		$logger        = $this->getApplication()->getLogger();
34
		$configuration = $this->getApplication()->getConfiguration();
35
36
		// Log information about the database
37
		$logger->debug('Using database at {databasePath}', [
38
			'databasePath' => $configuration->getDatabasePath(),
39
		]);
40
41
		// Log information about the configured instances
42
		$instances = $configuration->getInstances();
43
44
		$logger->info('Managing {instances} instances:', [
45
			'instances' => count($instances),
46
		]);
47
48
		foreach ($instances as $configuredInstance)
49
		{
50
			$instance = $configuredInstance->getInstance();
51
52
			$logger->info('  {address}:{port}', [
53
				'address' => $instance->getHostname(),
54
				'port'    => $instance->getPort(),
55
			]);
56
57
			$this->getApplication()->getEventDispatcher()
58
			     ->dispatch(Events::INSTANCE_SEEN, new InstanceSeenEvent($instance));
59
		}
60
	}
61
62
63
	/**
64
	 * Called periodically by the event loop. Here we inform the instance state manager
65
	 * that it should send us the current set of instances and their respective state.
66
	 */
67
	public function requestInstances()
68
	{
69
		$this->getApplication()->getEventDispatcher()->dispatch(Events::INSTANCE_COLLECTION_REQUEST);
70
	}
71
72
73
	/**
74
	 * Handles the INSTANCE_COLLECTION event
75
	 *
76
	 * @param InstanceCollectionEvent $event
77
	 */
78
	public function onInstanceCollection(InstanceCollectionEvent $event)
79
	{
80
		$logger          = $this->getApplication()->getLogger();
81
		$eventDispatcher = $this->getApplication()->getEventDispatcher();
82
83
		$statusCollection = $this->getStatusMessages($event->getInstances());
84
85
		foreach ($statusCollection->getInstanceStatuses() as $instanceStatus)
86
		{
87
			$instanceName = $instanceStatus->getInstanceName();
88
89
			$logger->debug('Got status updates from {instanceName}', [
90
				'instanceName' => $instanceName,
91
			]);
92
93
			// Persist connections
94
			foreach ($instanceStatus->getConnections() as $connection)
95
			{
96
				$eventDispatcher->dispatch(Events::CONNECTION_SEEN,
97
					new ConnectionSeenEvent($instanceName, $connection));
98
			}
99
100
			// Persist inputs
101
			foreach ($instanceStatus->getInputs() as $input)
102
				$eventDispatcher->dispatch(Events::INPUT_SEEN, new InputSeenEvent($instanceName, $input));
103
104
			// Persist running subscriptions
105
			foreach ($instanceStatus->getSubscriptions() as $subscription)
106
			{
107
				$eventDispatcher->dispatch(Events::SUBSCRIPTION_SEEN,
108
					new SubscriptionSeenEvent($instanceName, $subscription));
109
			}
110
111
			// Handle subscription state changes
112
			foreach ($instanceStatus->getSubscriptionStateChanges() as $subscriptionStateChange)
113
			{
114
				$eventDispatcher->dispatch(Events::SUBSCRIPTION_STATE_CHANGE,
115
					new SubscriptionStateChangeEvent($instanceName, $subscriptionStateChange));
116
			}
117
		}
118
119
		$eventDispatcher->dispatch(Events::INSTANCE_STATUS_UPDATES,
120
			new InstanceStatusUpdatesEvent($statusCollection));
121
	}
122
123
124
	/**
125
	 * Retrieves and returns all status messages for the configured
126
	 * instances
127
	 *
128
	 * @param \SplObjectStorage $instances the instances and their state
129
	 *
130
	 * @return InstanceStatusCollection
131
	 */
132
	private function getStatusMessages($instances)
133
	{
134
		$eventDispatcher = $this->getApplication()->getEventDispatcher();
135
		$collection      = new InstanceStatusCollection();
136
137
		foreach ($instances as $instance)
138
		{
139
			/* @var Instance $instance */
140
			$tvheadend     = $instance->getInstance();
141
			$instanceName  = $instance->getName();
142
			$instanceState = $instances[$instance];
143
144
			// Collect statuses from currently reachable instances
145
			if ($instanceState->isReachable())
146
			{
147
				try
148
				{
149
					$collection->add(new InstanceStatus(
150
						$instanceName,
151
						$tvheadend->getInputStatus(),
152
						$tvheadend->getSubscriptionStatus(),
153
						$tvheadend->getConnectionStatus(),
154
						StateChangeParser::parseStateChanges($tvheadend->getLogMessages())));
155
156
					$eventDispatcher->dispatch(Events::INSTANCE_STATE_REACHABLE,
157
						new InstanceStateEvent($instance));
158
				}
159
				catch (\Exception $e)
160
				{
161
					$eventDispatcher->dispatch(Events::INSTANCE_STATE_UNREACHABLE,
162
						new InstanceStateEvent($instance));
163
				}
164
			}
165
			else
166
			{
167
				$eventDispatcher->dispatch(Events::INSTANCE_STATE_MAYBE_REACHABLE,
168
					new InstanceStateEvent($instance));
169
			}
170
		}
171
172
		return $collection;
173
	}
174
175
}
176