Completed
Pull Request — master (#127)
by Matthew
17:36
created

QueueController::archiveAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
crap 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;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\StreamedResponse;
12
13
class QueueController
14
{
15
    use ControllerTrait;
16
17
    private $container;
18
19
    public function __construct(ContainerInterface $container)
20
    {
21
        $this->container = $container;
22
    }
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
    public function jobsAll()
44
    {
45 1
        $this->validateManagerType('dtc_queue.manager.job');
46
        $this->checkDtcGridBundle();
47 1
48 1
        $class1 = $this->container->getParameter('dtc_queue.class.job');
49
        $class2 = $this->container->getParameter('dtc_queue.class.job_archive');
50 1
        $label1 = 'Non-Archived Jobs';
51 1
        $label2 = 'Archived Jobs';
52 1
53 1
        $params = $this->getDualGridParams($class1, $class2, $label1, $label2);
54
55 1
        return $this->render('@DtcQueue/Queue/grid.html.twig', $params);
56
    }
57 1
58
    /**
59
     * @throws UnsupportedException
60
     */
61
    public function archive(Request $request)
62
    {
63
        return $this->streamResults($request, 'archiveAllJobs');
64
    }
65
66 1
    /**
67
     * @return StreamedResponse
68 1
     *
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
    protected function streamResults(Request $request, $functionName)
94
    {
95
        $jobManager = $this->container->get('dtc_queue.manager.job');
96
        if (!$jobManager instanceof DoctrineJobManager) {
97
            throw new UnsupportedException('$jobManager must be instance of '.DoctrineJobManager::class);
98
        }
99
100
        $streamingResponse = new StreamedResponse($this->getStreamFunction($request, $functionName));
101
        $streamingResponse->headers->set('Content-Type', 'application/x-ndjson');
102 1
        $streamingResponse->headers->set('X-Accel-Buffering', 'no');
103
104 1
        return $streamingResponse;
105 1
    }
106
107
    /**
108
     * @param string $functionName
109 1
     *
110 1
     * @return \Closure
111 1
     */
112
    protected function getStreamFunction(Request $request, $functionName)
113 1
    {
114
        $jobManager = $this->container->get('dtc_queue.manager.job');
115
        $workerName = $request->get('workerName');
116
        $methodName = $request->get('method');
117
        $total = null;
118
        $callback = function ($count, $totalCount) use (&$total) {
119
            if (null !== $totalCount && null === $total) {
120
                $total = $totalCount;
121 1
                echo json_encode(['total' => $total]);
122
                echo "\n";
123 1
                flush();
124 1
125 1
                return;
126 1
            }
127 1
            echo json_encode(['count' => $count]);
128
            echo "\n";
129
            flush();
130
        };
131
132
        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 1
                    if ($total > 0) {
140
                        $jobManager->archiveAllJobs($workerName, $methodName, $callback);
141 1
                    }
142
                    break;
143
                default:
144
                    $jobManager->$functionName($workerName, $methodName, $callback);
145
                    break;
146
            }
147
        };
148
    }
149
150
    /**
151
     * List jobs in system by default.
152
     *
153
     * @throws UnsupportedException|\Exception
154
     */
155
    public function jobs()
156 1
    {
157
        $this->validateManagerType('dtc_queue.manager.job');
158
        $this->checkDtcGridBundle();
159
        $managerType = $this->container->getParameter('dtc_queue.manager.job');
160
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
161
        $renderer = $rendererFactory->create('datatables');
162
        $gridSource = $this->container->get('dtc_queue.grid_source.jobs_waiting.'.('mongodb' === $managerType ? 'odm' : $managerType));
163
        $renderer->bind($gridSource);
164
        $params = $renderer->getParams();
165
        $this->addCssJs($params);
166
167 1
        $params['worker_methods'] = $this->container->get('dtc_queue.manager.job')->getWorkersAndMethods();
168
        $params['prompt_message'] = 'This will archive all non-running jobs';
169 1
170 1
        return $this->render('@DtcQueue/Queue/jobs.html.twig', $params);
171 1
    }
172 1
173 1
    /**
174 1
     * List jobs in system by default.
175 1
     *
176 1
     * @throws UnsupportedException|\Exception
177 1
     */
178
    public function jobsRunning()
179 1
    {
180 1
        $this->validateManagerType('dtc_queue.manager.job');
181
        $this->checkDtcGridBundle();
182 1
        $managerType = $this->container->getParameter('dtc_queue.manager.job');
183
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
184
        $renderer = $rendererFactory->create('datatables');
185
        $gridSource = $this->container->get('dtc_queue.grid_source.jobs_running.'.('mongodb' === $managerType ? 'odm' : $managerType));
186
        $renderer->bind($gridSource);
187
        $params = $renderer->getParams();
188
        $this->addCssJs($params);
189
190
        $params['worker_methods'] = $this->container->get('dtc_queue.manager.job')->getWorkersAndMethods(BaseJob::STATUS_RUNNING);
191
        $params['prompt_message'] = 'This will prune all stalled jobs';
192
193 1
        return $this->render('@DtcQueue/Queue/jobs_running.html.twig', $params);
194
    }
195 1
196 1
    /**
197 1
     * @param string $class1
198 1
     * @param string $class2
199 1
     * @param string $label1
200 1
     * @param string $label2
201 1
     *
202 1
     * @return array
203 1
     *
204
     * @throws \Exception
205 1
     */
206 1
    protected function getDualGridParams($class1, $class2, $label1, $label2)
207
    {
208 1
        $rendererFactory = $this->container->get('dtc_grid.renderer.factory');
209
        $renderer = $rendererFactory->create('datatables');
210
        $gridSource = $this->container->get('dtc_grid.manager.source')->get($class1);
211
        $renderer->bind($gridSource);
212
        $params = $renderer->getParams();
213
214
        $renderer2 = $rendererFactory->create('datatables');
215
        $gridSource = $this->container->get('dtc_grid.manager.source')->get($class2);
216
        $renderer2->bind($gridSource);
217
        $params2 = $renderer2->getParams();
218
219
        $params['archive_grid'] = $params2['dtc_grid'];
220
221 2
        $params['dtc_queue_grid_label1'] = $label1;
222
        $params['dtc_queue_grid_label2'] = $label2;
223 2
        $this->addCssJs($params);
224 2
225 2
        return $params;
226 2
    }
227 2
228
    /**
229 2
     * List jobs in system by default.
230 2
     *
231 2
     * @throws UnsupportedException|\Exception
232 2
     */
233
    public function runs()
234 2
    {
235
        $this->validateRunManager();
236 2
        $this->checkDtcGridBundle();
237 2
        $class1 = $this->container->getParameter('dtc_queue.class.run');
238 2
        $class2 = $this->container->getParameter('dtc_queue.class.run_archive');
239
        $label1 = 'Live Runs';
240 2
        $label2 = 'Archived Runs';
241
242
        $params = $this->getDualGridParams($class1, $class2, $label1, $label2);
243
244
        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 1
255 1
        $workerList = [];
256 1
        foreach ($workers as $workerName => $worker) {
257 1
            /* @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...
258
            $workerList[$workerName] = get_class($worker);
259 1
        }
260
        $params = ['workers' => $workerList];
261 1
        $this->addCssJs($params);
262
263
        return $this->render('@DtcQueue/Queue/workers.html.twig', $params);
264
    }
265
266
    /**
267
     * Validates that DtcGridBundle exists.
268
     *
269
     * @throws UnsupportedException
270 1
     */
271
    protected function checkDtcGridBundle()
272 1
    {
273 1
        if (!class_exists('Dtc\GridBundle\DtcGridBundle')) {
274
            throw new UnsupportedException('DtcGridBundle (mmucklo/grid-bundle) needs to be installed.');
275 1
        }
276 1
    }
277
}
278