Completed
Push — master ( 5fe2ea...bba9f0 )
by Matthew
13:23
created

WorkerCompilerPass::addLiveJobs()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 12
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 1
crap 12
1
<?php
2
3
namespace Dtc\QueueBundle\DependencyInjection\Compiler;
4
5
use Dtc\GridBundle\DependencyInjection\Compiler\GridSourceCompilerPass;
6
use Dtc\QueueBundle\Model\Job;
7
use Dtc\QueueBundle\Model\JobTiming;
8
use Dtc\QueueBundle\Model\Run;
9
use Dtc\QueueBundle\Exception\ClassNotFoundException;
10
use Dtc\QueueBundle\Exception\ClassNotSubclassException;
11
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
12
use Symfony\Component\DependencyInjection\Alias;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
use Symfony\Component\DependencyInjection\Definition;
16
use Symfony\Component\DependencyInjection\Reference;
17
18
class WorkerCompilerPass implements CompilerPassInterface
19
{
20
    public function process(ContainerBuilder $container)
21
    {
22
        if (false === $container->hasDefinition('dtc_queue.worker_manager')) {
23
            return;
24
        }
25
26
        $this->setupAliases($container);
27
28
        $definition = $container->getDefinition('dtc_queue.worker_manager');
29
30
        $jobClass = $this->getJobClass($container);
31
        $jobArchiveClass = $this->getJobClassArchive($container);
32
        $container->setParameter('dtc_queue.class_job', $jobClass);
33
        $container->setParameter('dtc_queue.class_job_archive', $jobArchiveClass);
34
35
        $managerType = $this->getRunManagerType($container);
36
        $jobTimingManagerType = $this->getJobTimingManagerType($container);
37
        $container->setParameter('dtc_queue.class_job_timing', $this->getClass(
38
            $container,
39
            $jobTimingManagerType,
40
            'job_timing',
41
            'JobTiming',
42
            JobTiming::class
43
        ));
44
        $container->setParameter('dtc_queue.class_run', $this->getClass($container, $managerType, 'run', 'Run', Run::class));
45
        $container->setParameter('dtc_queue.class_run_archive', $this->getClass($container, $managerType, 'run_archive', 'RunArchive', Run::class));
46
47
        $this->setupTaggedServices($container, $definition, $jobClass);
48
        $eventDispatcher = $container->getDefinition('dtc_queue.event_dispatcher');
49
        foreach ($container->findTaggedServiceIds('dtc_queue.event_subscriber') as $id => $attributes) {
50
            $eventSubscriber = $container->getDefinition($id);
51
            $eventDispatcher->addMethodCall('addSubscriber', [$eventSubscriber]);
52
        }
53
        $this->setupDoctrineManagers($container);
54
        $this->addLiveJobs($container);
55
    }
56
57
    protected function setupAlias(ContainerBuilder $container, $defaultManagerType, $type)
58
    {
59
        $definitionName = 'dtc_queue.'.$type.'.'.$defaultManagerType;
60
        if (!$container->hasDefinition($definitionName) && !$container->hasAlias($definitionName)) {
61
            throw new InvalidConfigurationException("No $type manager found for dtc_queue.$type.$defaultManagerType");
62
        }
63
        if ($container->hasDefinition($definitionName)) {
64
            $alias = new Alias('dtc_queue.'.$type.'.'.$defaultManagerType);
65
            $alias->setPublic(true);
66
            $container->setAlias('dtc_queue.'.$type, $alias);
67
68
            return;
69
        }
70
71
        $container->getAlias($definitionName)->setPublic(true);
72
        $container->setAlias('dtc_queue.'.$type, $container->getAlias($definitionName));
73
    }
74
75
    protected function setupAliases(ContainerBuilder $container)
76
    {
77
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
78
        $this->setupAlias($container, $defaultManagerType, 'job_manager');
79
        $runManagerType = $container->getParameter($this->getRunManagerType($container));
80
        $this->setupAlias($container, $runManagerType, 'run_manager');
81
        $jobTimingManagerType = $container->getParameter($this->getJobTimingManagerType($container));
82
        $this->setupAlias($container, $jobTimingManagerType, 'job_timing_manager');
83
    }
84
85
    /**
86
     * @param ContainerBuilder $container
87
     * @param Reference[]      $jobManagerRef
0 ignored issues
show
Bug introduced by
There is no parameter named $jobManagerRef. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
88
     * @param string           $jobClass
89
     */
90
    protected function setupTaggedServices(ContainerBuilder $container, Definition $definition, $jobClass)
91
    {
92
        $jobManagerRef = array(new Reference('dtc_queue.job_manager'));
93
        // Add each worker to workerManager, make sure each worker has instance to work
94
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
95
            $worker = $container->getDefinition($id);
96
            $class = $container->getDefinition($id)->getClass();
97
98
            $refClass = new \ReflectionClass($class);
99
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
100
            if (!$refClass->isSubclassOf($workerClass)) {
101
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
102
            }
103
104
            // Give each worker access to job manager
105
            $worker->addMethodCall('setJobManager', $jobManagerRef);
106
            $worker->addMethodCall('setJobClass', array($jobClass));
107
108
            $definition->addMethodCall('addWorker', array(new Reference($id)));
109
        }
110
    }
111
112
    /**
113
     * @param ContainerBuilder $container
114
     */
115
    protected function setupDoctrineManagers(ContainerBuilder $container)
116
    {
117
        $documentManager = $container->getParameter('dtc_queue.document_manager');
118
119
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
120
        if ($container->has($odmManager)) {
121
            $container->setAlias('dtc_queue.document_manager', $odmManager);
122
        }
123
124
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
125
126
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
127
        if ($container->has($ormManager)) {
128
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
129
        }
130
    }
131
132
    /**
133
     * @param ContainerBuilder $container
134
     */
135
    protected function addLiveJobs(ContainerBuilder $container)
136
    {
137
        $jobReflection = new \ReflectionClass($container->getParameter('dtc_queue.class_job'));
138
        if ($jobReflection->isInstance(new \Dtc\QueueBundle\Document\Job())) {
139
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.jobs_waiting.odm');
140
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.jobs_running.odm');
141
        }
142
        if ($jobReflection->isInstance(new \Dtc\QueueBundle\Entity\Job())) {
143
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.jobs_waiting.orm');
144
            GridSourceCompilerPass::addGridSource($container, 'dtc_queue.grid_source.jobs_running.orm');
145
        }
146
    }
147
148
    /**
149
     * @param $managerType
150
     *
151
     * @return null|string
152
     */
153
    protected function getDirectory($managerType)
154
    {
155
        switch ($managerType) {
156
            case 'mongodb': // deprecated remove in 3.0
157
            case 'odm':
158
                return 'Document';
159
            case 'beanstalkd':
160
                return 'Beanstalkd';
161
            case 'rabbit_mq':
162
                return 'RabbitMQ';
163
            case 'orm':
164
                return 'Entity';
165
        }
166
167
        return null;
168
    }
169
170
    /**
171
     * Determines the job class based on the queue manager type.
172
     *
173
     * @param ContainerBuilder $container
174
     *
175
     * @return mixed|string
176
     *
177
     * @throws InvalidConfigurationException
178
     */
179
    protected function getJobClass(ContainerBuilder $container)
180
    {
181
        $jobClass = $container->getParameter('dtc_queue.class_job');
182
        if (!$jobClass) {
183
            if ($directory = $this->getDirectory($managerType = $container->getParameter('dtc_queue.default_manager'))) {
184
                $jobClass = 'Dtc\QueueBundle\\'.$directory.'\Job';
185
            } else {
186
                throw new InvalidConfigurationException('Unknown default_manager type '.$managerType.' - please specify a Job class in the \'class\' configuration parameter');
187
            }
188
        }
189
190
        $this->testClass($jobClass, Job::class);
191
192
        return $jobClass;
193
    }
194
195
    protected function getRunManagerType(ContainerBuilder $container)
196
    {
197
        $managerType = 'dtc_queue.default_manager';
198
        if ($container->hasParameter('dtc_queue.run_manager')) {
199
            $managerType = 'dtc_queue.run_manager';
200
        }
201
202
        return $managerType;
203
    }
204
205
    protected function getJobTimingManagerType(ContainerBuilder $container)
206
    {
207
        $managerType = $this->getRunManagerType($container);
208
        if ($container->hasParameter('dtc_queue.job_timing_manager')) {
209
            $managerType = 'dtc_queue.job_timing_manager';
210
        }
211
212
        return $managerType;
213
    }
214
215
    protected function getClass(ContainerBuilder $container, $managerType, $type, $className, $baseClass)
216
    {
217
        $runClass = $container->hasParameter('dtc_queue.class_'.$type) ? $container->getParameter('dtc_queue.class_'.$type) : null;
218
        if (!$runClass) {
219
            switch ($container->getParameter($managerType)) {
220
                case 'mongodb': // deprecated remove in 3.0
221
                case 'odm':
222
                    $runClass = 'Dtc\\QueueBundle\\Document\\'.$className;
223
                    break;
224
                case 'orm':
225
                    $runClass = 'Dtc\\QueueBundle\\Entity\\'.$className;
226
                    break;
227
                default:
228
                    $runClass = $baseClass;
229
            }
230
        }
231
232
        $this->testClass($runClass, $baseClass);
233
234
        return $runClass;
235
    }
236
237
    /**
238
     * @throws ClassNotFoundException
239
     * @throws ClassNotSubclassException
240
     */
241
    protected function testClass($className, $parent)
242
    {
243
        if (!class_exists($className)) {
244
            throw new ClassNotFoundException("Can't find class $className");
245
        }
246
247
        $test = new $className();
248
        if (!$test instanceof $className) {
249
            throw new ClassNotSubclassException("$className must be instance of (or derived from) $parent");
250
        }
251
    }
252
253
    /**
254
     * Determines the job class based on the queue manager type.
255
     *
256
     * @param ContainerBuilder $container
257
     *
258
     * @return mixed|string
259
     *
260
     * @throws ClassNotFoundException
261
     * @throws ClassNotSubclassException
262
     */
263
    protected function getJobClassArchive(ContainerBuilder $container)
264
    {
265
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
266
        if (!$jobArchiveClass) {
267
            switch ($container->getParameter('dtc_queue.default_manager')) {
268
                case 'mongodb': // deprecated remove in 4.0
269
                case 'odm':
270
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
271
                    break;
272
                case 'orm':
273
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
274
                    break;
275
            }
276
        }
277
        if (null !== $jobArchiveClass) {
278
            $this->testClass($jobArchiveClass, Job::class);
279
        }
280
281
        return $jobArchiveClass;
282
    }
283
}
284