Completed
Push — master ( 6553f8...615432 )
by Robin
06:51 queued 03:39
created

CrawlController::failCrawler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 5
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Famdirksen\LaravelJobHandler\Http\Controllers;
4
5
use Carbon\Carbon;
6
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerException;
7
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerNotReachedTimeBetweenJobsException;
8
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerSaveException;
9
use Famdirksen\LaravelJobHandler\Models\Crawlers;
10
use Famdirksen\LaravelJobHandler\Models\CrawlerStatus;
11
use Famdirksen\LaravelJobHandler\Models\CrawlerStatusLogs;
12
13
class CrawlController
14
{
15
    protected $crawler;
16
    protected $crawler_id;
17
18
19
    /**
20
     * Get the latest crawler data from the database
21
     */
22
    protected function getCrawler()
23
    {
24
        if (empty($this->crawler) || $this->crawler->id != $this->crawler_id) {
25
            $this->crawler = Crawlers::findOrFail($this->crawler_id);
26
        } else {
27
            $this->crawler = $this->crawler->fresh();
28
        }
29
    }
30
31
    /**
32
     * Set the crawler id
33
     *
34
     * @param $crawler_id
35
     */
36
    public function setCrawlerId($crawler_id)
37
    {
38
        $this->crawler_id = $crawler_id;
39
    }
40
41
    /**
42
     * Return the crawler id
43
     *
44
     * @return mixed
45
     */
46
    public function getCrawlerId() {
47
        return $this->crawler_id;
48
    }
49
50
    /**
51
     * Check if the controller is setup correctly
52
     *
53
     * @return bool
54
     */
55
    protected function controllerIsSetup() {
56
        if(!is_null($this->crawler_id)) {
57
            return true;
58
        }
59
60
        return false;
61
    }
62
63
    /**
64
     * Setup the crawler so it won't run twice at the same time
65
     *
66
     * @param $crawler_id
67
     */
68
    public function setupCrawler($crawler_id = null)
69
    {
70
        if(!is_null($crawler_id)) {
71
            $this->setCrawlerId($crawler_id);
72
        }
73
74
        if($this->controllerIsSetup()) {
75
            $times = config('laravel-job-handler.run_times', 10);
76
77
            for ($x = 0; $x <= $times; $x++) {
78
                //fetch the last data
79
                $this->getCrawler();
80
81
                if (!$this->crawler->enabled) {
82
                    throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - crawler isnt enabled in database');
83
                }
84
85
                $checkIfCrawlerCanBeRunned = $this->canCrawlerRunAfterPeriod();
86
87
                if ($checkIfCrawlerCanBeRunned['status']) {
88
                    if (is_null($this->crawler->latest_status)) {
89
                        //first time it runs...
90
                        break;
91
                    }
92
                    if ($this->crawler->latest_status == 2) {
93
                        //Done running...
94
                        break;
95
                    }
96
97
98
                    if ($this->crawler->latest_status == 3) {
99
                        throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - last run had an error');
100
                    }
101
                } else {
102
                    throw new CrawlerNotReachedTimeBetweenJobsException('Has to wait ' . $checkIfCrawlerCanBeRunned['retry_in'] . ' more seconds to run');
103
                }
104
105
                if ($x == $times) {
106
                    $this->failCrawler('Crawler (#' . $this->crawler_id . ') - max execution time');
107
                }
108
109
                if ($this->crawler->status == 1) {
110
                    if ($this->crawler->multiple_crawlers) {
111
                        break;
112
                    }
113
114
                    sleep(config('laravel-job-handler.retry_in_seconds', 3)); //retry in 3 seconds
115
                }
116
            }
117
118
            $this->startCrawler();
119
        } else {
120
            throw new CrawlerException('CrawlController is not setup correctly.');
121
        }
122
    }
123
    /**
124
     * Start the crawler and save it to the database
125
     *
126
     * @param string $output
127
     */
128
    public function startCrawler($output = '')
129
    {
130
        return $this->addStatus(1, $output); //start running
131
    }
132
    /**
133
     * set the crawler as done so other scripts can run
134
     *
135
     * @param string $output
136
     */
137
    public function doneCrawler($output = '')
138
    {
139
        return $this->addStatus(2, $output); //done running
140
    }
141
142
    /**
143
     * Finishing the crawler
144
     *
145
     * @param string $output
146
     * @return bool
147
     */
148
    public function finish($output = '')
149
    {
150
        return $this->doneCrawler($output);
151
    }
152
    /**
153
     * crawler failed...
154
     *
155
     * @param string $output
156
     */
157
    public function failCrawler($output = '')
158
    {
159
        $this->addStatus(3, $output); //failed
160
161
        throw new CrawlerException($output.' - status 3');
162
    }
163
    /**
164
     * Save the latest crawler status to the database
165
     *
166
     * @param $status
167
     * @param string $output
168
     * @return bool
169
     */
170
    protected function addStatus($status, $output = '')
171
    {
172
        $crawlerstatus = new CrawlerStatus();
173
174
        $crawlerstatus->crawler_id = $this->crawler_id;
175
        $crawlerstatus->status = $status;
176
177
        if ($crawlerstatus->save()) {
178
            $this->crawler->latest_status = $status;
179
180
            $this->crawler->save();
181
182
            if (!empty($output)) {
183
                $crawlerstatuslog = new CrawlerStatusLogs();
184
185
                $crawlerstatuslog->status_id = $crawlerstatus->id;
0 ignored issues
show
Bug introduced by
The property status_id does not seem to exist on Famdirksen\LaravelJobHan...odels\CrawlerStatusLogs. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
186
                $crawlerstatuslog->output = $output;
0 ignored issues
show
Bug introduced by
The property output does not seem to exist on Famdirksen\LaravelJobHan...odels\CrawlerStatusLogs. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
187
188
                $crawlerstatuslog->save();
189
            }
190
191
            return true;
192
        } else {
193
            throw new CrawlerSaveException('Cannot save crawlerstatus to database...');
194
        }
195
    }
196
197
    /**
198
     * This will define when the job can be runned again
199
     *
200
     * @return array
201
     */
202
    public function canCrawlerRunAfterPeriod()
203
    {
204
        $this->getCrawler();
205
206
        if (is_null($this->crawler->time_between)) {
207
            return $this->canCrawlerRunAfterPeriodStatus(true);
208
        } else {
209
            $seconds = $this->crawler->time_between;
210
        }
211
212
        if (!is_null($this->crawler->last_runned_at)) {
213
            if ($this->crawler->last_runned_at <= Carbon::now()->subSeconds($seconds)) {
214
                return $this->canCrawlerRunAfterPeriodStatus(true);
215
            }
216
217
            return $this->canCrawlerRunAfterPeriodStatus(false, Carbon::parse($this->crawler->last_runned_at)->diffInSeconds(Carbon::now()->subSeconds($seconds)));
218
        } else {
219
            //crawler never runned, so it can run now
220
            return $this->canCrawlerRunAfterPeriodStatus(true);
221
        }
222
    }
223
224
    /**
225
     * Return the status for canCrawlerRunAfterPeriod method
226
     *
227
     * @param $status
228
     * @param int $retry_in
229
     * @return array
230
     */
231
    public function canCrawlerRunAfterPeriodStatus($status, $retry_in = 0)
232
    {
233
        return [
234
            'status' => $status,
235
            'retry_in' => $retry_in
236
        ];
237
    }
238
}
239