Passed
Push — master ( 35a7ab...d29e83 )
by Matthew
07:21
created

QueueController::jobsAction()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 12
nc 1
nop 0
dl 0
loc 16
ccs 13
cts 13
cp 1
crap 2
rs 9.8666
c 1
b 0
f 0
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 Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
10
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
12
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\StreamedResponse;
15
16
class QueueController extends Controller
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Bundle\Framework...e\Controller\Controller has been deprecated: since Symfony 4.2, use "Symfony\Bundle\FrameworkBundle\Controller\AbstractController" instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

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

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
282
            $workerList[$workerName] = get_class($worker);
283
        }
284 1
        $params = ['workers' => $workerList];
285 1
        $this->addCssJs($params);
286
287 1
        return $params;
288
    }
289
290
    /**
291
     * Validates that DtcGridBundle exists
292
     * @throws UnsupportedException
293
     */
294 4
    protected function checkDtcGridBundle() {
295 4
        if (!class_exists('Dtc\GridBundle\DtcGridBundle')) {
296
            throw new UnsupportedException("DtcGridBundle (mmucklo/grid-bundle) needs to be installed.");
297
        }
298 4
    }
299
}
300