Failed Conditions
Push — newinternal ( b66232...216d62 )
by Simon
16:33 queued 06:35
created

RunJobQueueTask::execute()   F

Complexity

Conditions 8
Paths 1244

Size

Total Lines 82

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 1244
nop 0
dl 0
loc 82
rs 3.8149
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\ConsoleTasks;
10
11
use Exception;
12
use PDO;
13
use Waca\Background\BackgroundTaskBase;
14
use Waca\Background\Task\BotCreationTask;
15
use Waca\Background\Task\UserCreationTask;
16
use Waca\Background\Task\WelcomeUserTask;
17
use Waca\DataObjects\JobQueue;
18
use Waca\DataObjects\Request;
19
use Waca\Exceptions\ApplicationLogicException;
20
use Waca\Helpers\Logger;
21
use Waca\Tasks\ConsoleTaskBase;
22
23
class RunJobQueueTask extends ConsoleTaskBase
24
{
25
    private $taskList = array(
26
        WelcomeUserTask::class,
27
        BotCreationTask::class,
28
        UserCreationTask::class
29
    );
30
31
    public function execute()
32
    {
33
        $database = $this->getDatabase();
34
35
        // ensure we're running inside a tx here.
36
        if (!$database->hasActiveTransaction()) {
37
            $database->beginTransaction();
38
        }
39
40
        $sql = 'SELECT * FROM jobqueue WHERE status = :status ORDER BY enqueue LIMIT :lim';
41
        $statement = $database->prepare($sql);
42
        $statement->execute(array(':status' => JobQueue::STATUS_READY, ':lim' => 10));
43
        /** @var JobQueue[] $queuedJobs */
44
        $queuedJobs = $statement->fetchAll(PDO::FETCH_CLASS, JobQueue::class);
45
46
        // mark all the jobs as running, and commit the txn so we're not holding onto long-running transactions.
47
        // We'll re-lock the row when we get to it.
48
        foreach ($queuedJobs as $job) {
49
            $job->setDatabase($database);
50
            $job->setStatus(JobQueue::STATUS_WAITING);
51
            $job->setError(null);
52
            $job->setAcknowledged(null);
53
            $job->save();
54
        }
55
56
        $database->commit();
57
58
        set_error_handler(array(RunJobQueueTask::class, 'errorHandler'), E_ALL);
59
60
        foreach ($queuedJobs as $job) {
61
            try {
62
                $database->beginTransaction();
63
64
                // re-lock the job
65
                $job->setStatus(JobQueue::STATUS_RUNNING);
66
                $job->save();
67
68
                // validate we're allowed to run the requested task (whitelist)
69
                if (!in_array($job->getTask(), $this->taskList)) {
70
                    throw new ApplicationLogicException('Job task not registered');
71
                }
72
73
                // Create a task.
74
                $taskName = $job->getTask();
75
76
                if(!class_exists($taskName)) {
77
                    throw new ApplicationLogicException('Job task does not exist');
78
                }
79
80
                /** @var BackgroundTaskBase $task */
81
                $task = new $taskName;
82
83
                $this->setupTask($task, $job);
84
                $task->run();
85
            }
86
            catch (Exception $ex) {
87
                $database->rollBack();
88
                $database->beginTransaction();
89
90
                /** @var JobQueue $job */
91
                $job = JobQueue::getById($job->getId(), $database);
92
                $job->setDatabase($database);
93
                $job->setStatus(JobQueue::STATUS_FAILED);
94
                $job->setError($ex->getMessage());
95
                $job->setAcknowledged(0);
96
                $job->save();
97
98
                /** @var Request $request */
99
                $request = Request::getById($job->getRequest(), $database);
100
                if ($request === false) {
101
                    $request = null;
102
                }
103
104
                Logger::backgroundJobIssue($this->getDatabase(), $job);
105
106
                $database->commit();
107
            }
108
            finally {
109
                $database->commit();
110
            }
111
        }
112
    }
113
114
    /**
115
     * @param BackgroundTaskBase $task
116
     * @param JobQueue           $job
117
     */
118
    private function setupTask(BackgroundTaskBase $task, JobQueue $job)
119
    {
120
        $task->setJob($job);
121
        $task->setDatabase($this->getDatabase());
122
        $task->setHttpHelper($this->getHttpHelper());
123
        $task->setOauthProtocolHelper($this->getOAuthProtocolHelper());
124
        $task->setEmailHelper($this->getEmailHelper());
125
        $task->setSiteConfiguration($this->getSiteConfiguration());
126
        $task->setNotificationHelper($this->getNotificationHelper());
127
    }
128
129
    public static function errorHandler($errno, $errstr, $errfile, $errline) {
0 ignored issues
show
Unused Code introduced by
The parameter $errno is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
130
        throw new Exception($errfile . "@" . $errline . ": " . $errstr);
131
    }
132
}