QueueController   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 262
Duplicated Lines 0 %

Test Coverage

Coverage 78.23%

Importance

Changes 3
Bugs 1 Features 0
Metric Value
eloc 110
c 3
b 1
f 0
dl 0
loc 262
ccs 97
cts 124
cp 0.7823
rs 10
wmc 23

14 Methods

Rating   Name   Duplication   Size   Complexity  
A status() 0 9 1
A jobsRunning() 0 16 2
A streamResults() 0 12 2
A jobsAll() 0 13 1
A archive() 0 3 1
A runs() 0 12 1
A jobs() 0 16 2
A workers() 0 14 2
A getDualGridParams() 0 20 1
A pruneStalled() 0 3 1
A __construct() 0 3 1
A checkDtcGridBundle() 0 4 2
A getStreamFunction() 0 34 5
A resetStalled() 0 3 1
1
<?php
2
3
namespace Dtc\QueueBundle\Controller;
4
5
use Dtc\QueueBundle\Doctrine\DoctrineJobManager;
6
use Dtc\QueueBundle\Exception\UnsupportedException;
7
use Dtc\QueueBundle\Model\BaseJob;
8
use Dtc\QueueBundle\Model\Worker;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Depend...tion\ContainerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
10
use Symfony\Component\HttpFoundation\Request;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Symfony\Component\HttpFoundation\StreamedResponse;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpFoundation\StreamedResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
13
class QueueController
14
{
15 1
    use ControllerTrait;
16
17
    private $container;
18
19 7
    public function __construct(ContainerInterface $container)
20
    {
21 7
        $this->container = $container;
22 7
    }
23
24
    /**
25
     * Summary stats.
26
     */
27 1
    public function status()
28
    {
29 1
        $params = [];
30 1
        $jobManager = $this->container->get('dtc_queue.manager.job');
31
32 1
        $params['status'] = $jobManager->getStatus();
33 1
        $this->addCssJs($params);
34
35 1
        return $this->render('@DtcQueue/Queue/status.html.twig', $params);
36
    }
37
38
    /**
39
     * List jobs in system by default.
40
     *
41
     * @throws UnsupportedException|\Exception
42
     */
43 1
    public function jobsAll()
44
    {
45 1
        $this->validateManagerType('dtc_queue.manager.job');
46 1
        $this->checkDtcGridBundle();
47
48 1
        $class1 = $this->container->getParameter('dtc_queue.class.job');
49 1
        $class2 = $this->container->getParameter('dtc_queue.class.job_archive');
50 1
        $label1 = 'Non-Archived Jobs';
51 1
        $label2 = 'Archived Jobs';
52
53 1
        $params = $this->getDualGridParams($class1, $class2, $label1, $label2);
54
55 1
        return $this->render('@DtcQueue/Queue/grid.html.twig', $params);
56
    }
57
58
    /**
59
     * @throws UnsupportedException
60
     */
61 1
    public function archive(Request $request)
62
    {
63 1
        return $this->streamResults($request, 'archiveAllJobs');
64
    }
65
66
    /**
67
     * @return StreamedResponse
68
     *
69
     * @throws UnsupportedException
70
     */
71
    public function resetStalled(Request $request)
72
    {
73
        return $this->streamResults($request, 'resetStalledJobs');
74
    }
75
76
    /**
77
     * @return StreamedResponse
78
     *
79
     * @throws UnsupportedException
80
     */
81
    public function pruneStalled(Request $request)
82
    {
83
        return $this->streamResults($request, 'pruneStalledJobs');
84
    }
85
86
    /**
87
     * @param $functionName
88
     *
89
     * @return StreamedResponse
90
     *
91
     * @throws UnsupportedException
92
     */
93 1
    protected function streamResults(Request $request, $functionName)
94
    {
95 1
        $jobManager = $this->container->get('dtc_queue.manager.job');
96 1
        if (!$jobManager instanceof DoctrineJobManager) {
97
            throw new UnsupportedException('$jobManager must be instance of '.DoctrineJobManager::class);
98
        }
99
100 1
        $streamingResponse = new StreamedResponse($this->getStreamFunction($request, $functionName));
101 1
        $streamingResponse->headers->set('Content-Type', 'application/x-ndjson');
102 1
        $streamingResponse->headers->set('X-Accel-Buffering', 'no');
103
104 1
        return $streamingResponse;
105
    }
106
107
    /**
108
     * @param string $functionName
109
     *
110
     * @return \Closure
111
     */
112 1
    protected function getStreamFunction(Request $request, $functionName)
113
    {
114 1
        $jobManager = $this->container->get('dtc_queue.manager.job');
115 1
        $workerName = $request->get('workerName');
116 1
        $methodName = $request->get('method');
117 1
        $total = null;
118 1
        $callback = function ($count, $totalCount) use (&$total) {
119
            if (null !== $totalCount && null === $total) {
120
                $total = $totalCount;
121
                echo json_encode(['total' => $total]);
122
                echo "\n";
123
                flush();
124
125
                return;
126
            }
127
            echo json_encode(['count' => $count]);
128
            echo "\n";
129
            flush();
130 1
        };
131
132 1
        return function () use ($jobManager, $callback, $workerName, $methodName, $functionName, &$total) {
133
            switch ($functionName) {
134
                case 'archiveAllJobs':
135
                    $total = $jobManager->countLiveJobs($workerName, $methodName);
136
                    echo json_encode(['total' => $total]);
137
                    echo "\n";
138
                    flush();
139
                    if ($total > 0) {
140
                        $jobManager->archiveAllJobs($workerName, $methodName, $callback);
141
                    }
142
                    break;
143
                default:
144
                    $jobManager->$functionName($workerName, $methodName, $callback);
145
                    break;
146
            }
147 1
        };
148
    }
149
150
    /**
151
     * List jobs in system by default.
152
     *
153
     * @throws UnsupportedException|\Exception
154
     */
155 1
    public function jobs()
156
    {
157 1
        $this->validateManagerType('dtc_queue.manager.job');
158 1
        $this->checkDtcGridBundle();
159 1
        $managerType = $this->container->getParameter('dtc_queue.manager.job');
160 1
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
161 1
        $renderer = $rendererFactory->create('datatables');
162 1
        $gridSource = $this->container->get('dtc_queue.grid_source.jobs_waiting.'.('mongodb' === $managerType ? 'odm' : $managerType));
163 1
        $renderer->bind($gridSource);
164 1
        $params = $renderer->getParams();
165 1
        $this->addCssJs($params);
166
167 1
        $params['worker_methods'] = $this->container->get('dtc_queue.manager.job')->getWorkersAndMethods();
168 1
        $params['prompt_message'] = 'This will archive all non-running jobs';
169
170 1
        return $this->render('@DtcQueue/Queue/jobs.html.twig', $params);
171
    }
172
173
    /**
174
     * List jobs in system by default.
175
     *
176
     * @throws UnsupportedException|\Exception
177
     */
178 1
    public function jobsRunning()
179
    {
180 1
        $this->validateManagerType('dtc_queue.manager.job');
181 1
        $this->checkDtcGridBundle();
182 1
        $managerType = $this->container->getParameter('dtc_queue.manager.job');
183 1
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
184 1
        $renderer = $rendererFactory->create('datatables');
185 1
        $gridSource = $this->container->get('dtc_queue.grid_source.jobs_running.'.('mongodb' === $managerType ? 'odm' : $managerType));
186 1
        $renderer->bind($gridSource);
187 1
        $params = $renderer->getParams();
188 1
        $this->addCssJs($params);
189
190 1
        $params['worker_methods'] = $this->container->get('dtc_queue.manager.job')->getWorkersAndMethods(BaseJob::STATUS_RUNNING);
191 1
        $params['prompt_message'] = 'This will prune all stalled jobs';
192
193 1
        return $this->render('@DtcQueue/Queue/jobs_running.html.twig', $params);
194
    }
195
196
    /**
197
     * @param string $class1
198
     * @param string $class2
199
     * @param string $label1
200
     * @param string $label2
201
     *
202
     * @return array
203
     *
204
     * @throws \Exception
205
     */
206 2
    protected function getDualGridParams($class1, $class2, $label1, $label2)
207
    {
208 2
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
209 2
        $renderer = $rendererFactory->create('datatables');
210 2
        $gridSource = $this->container->get('dtc_grid.manager.source')->get($class1);
211 2
        $renderer->bind($gridSource);
212 2
        $params = $renderer->getParams();
213
214 2
        $renderer2 = $rendererFactory->create('datatables');
215 2
        $gridSource = $this->container->get('dtc_grid.manager.source')->get($class2);
216 2
        $renderer2->bind($gridSource);
217 2
        $params2 = $renderer2->getParams();
218
219 2
        $params['archive_grid'] = $params2['dtc_grid'];
220
221 2
        $params['dtc_queue_grid_label1'] = $label1;
222 2
        $params['dtc_queue_grid_label2'] = $label2;
223 2
        $this->addCssJs($params);
224
225 2
        return $params;
226
    }
227
228
    /**
229
     * List jobs in system by default.
230
     *
231
     * @throws UnsupportedException|\Exception
232
     */
233 1
    public function runs()
234
    {
235 1
        $this->validateRunManager();
236 1
        $this->checkDtcGridBundle();
237 1
        $class1 = $this->container->getParameter('dtc_queue.class.run');
238 1
        $class2 = $this->container->getParameter('dtc_queue.class.run_archive');
239 1
        $label1 = 'Live Runs';
240 1
        $label2 = 'Archived Runs';
241
242 1
        $params = $this->getDualGridParams($class1, $class2, $label1, $label2);
243
244 1
        return $this->render('@DtcQueue/Queue/grid.html.twig', $params);
245
    }
246
247
    /**
248
     * List registered workers in the system.
249
     */
250 1
    public function workers()
251
    {
252 1
        $workerManager = $this->container->get('dtc_queue.manager.worker');
253 1
        $workers = $workerManager->getWorkers();
254
255 1
        $workerList = [];
256 1
        foreach ($workers as $workerName => $worker) {
257
            /* @var Worker $worker */
258
            $workerList[$workerName] = get_class($worker);
259
        }
260 1
        $params = ['workers' => $workerList];
261 1
        $this->addCssJs($params);
262
263 1
        return $this->render('@DtcQueue/Queue/workers.html.twig', $params);
264
    }
265
266
    /**
267
     * Validates that DtcGridBundle exists.
268
     *
269
     * @throws UnsupportedException
270
     */
271 4
    protected function checkDtcGridBundle()
272
    {
273 4
        if (!class_exists('Dtc\GridBundle\DtcGridBundle')) {
274
            throw new UnsupportedException('DtcGridBundle (mmucklo/grid-bundle) needs to be installed.');
275
        }
276 4
    }
277
}
278