Completed
Push — master ( 3dfec0...098987 )
by Sam
03:00
created

StatusManager::getSubscribedEvents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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