Passed
Pull Request — master (#130)
by
unknown
03:04
created

Job::process()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 3
nop 0
dl 0
loc 16
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\StaticPublishQueue;
4
5
use SilverStripe\Core\Config\Configurable;
6
use SilverStripe\Core\Extensible;
7
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
8
9
/**
10
 * Class Job
11
 *
12
 * @property array $URLsToProcess
13
 * @property array $ProcessedURLs
14
 * @package SilverStripe\StaticPublishQueue
15
 */
16
abstract class Job extends AbstractQueuedJob
17
{
18
    use Configurable;
19
    use Extensible;
20
21
    /**
22
     * Number of URLs processed during one call of @see AbstractQueuedJob::process()
23
     * this number should be set to a value which represents number of URLs which is reasonable to process in one go
24
     * this number will vary depending on project, more specifically it depends on:
25
     * - time to render your pages
26
     * - infrastructure
27
     *
28
     * if this number is too large jobs may experience performance / memory issues
29
     * if this number is too low the jobs will produce more overhead which may cause inefficiencies
30
     *
31
     * in case you project is complex and you are struggling to find the correct number
32
     * it's possible to move this value to a CMS setting and adjust as needed without the need of changing the code
33
     * use @see Job::getChunkSize() to override the value lookup
34
     * you can subclass your jobs and implement your own getChunkSize() method which will look into CMS setting
35
     *
36
     * chunking capability can be disabled if chunk size is set to 0
37
     * in such case, all URLs will be processed in one go
38
     *
39
     * @var int
40
     * @config
41
     */
42
    private static $chunk_size = 200;
0 ignored issues
show
introduced by
The private property $chunk_size is not used, and could be removed.
Loading history...
43
44
    /**
45
     * Static cache manipulation jobs need to run without a user
46
     * this is because we don't want any session related data to become part of URLs
47
     * For example stage GET param is injected into URLs when user is logged in
48
     * This is problematic as stage param must not be present in statically published URLs
49
     * as they always refer to live content
50
     * Including stage param in visiting URL is meant to bypass static cache and redirect to admin login
51
     * this is something we definitely don't want for statically cached pages
52
     *
53
     * @return int|null
54
     */
55
    public function getRunAsMemberID(): ?int
56
    {
57
        return 0;
58
    }
59
60
    public function setup(): void
61
    {
62
        parent::setup();
63
        $this->totalSteps = count($this->URLsToProcess);
64
    }
65
66
    public function getSignature(): string
67
    {
68
        return md5(implode('-', [static::class, implode('-', array_keys($this->URLsToProcess))]));
69
    }
70
71
    public function process(): void
72
    {
73
        $chunkSize = $this->getChunkSize();
74
        $count = 0;
75
76
        foreach ($this->URLsToProcess as $url => $priority) {
77
            $count += 1;
78
79
            if ($chunkSize > 0 && $count > $chunkSize) {
80
                return;
81
            }
82
83
            $this->processUrl($url, $priority);
84
        }
85
86
        $this->updateCompletedState();
87
    }
88
89
    /**
90
     * Implement this method to process URL
91
     *
92
     * @param string $url
93
     * @param int $priority
94
     */
95
    abstract protected function processUrl(string $url, int $priority): void;
96
97
    /**
98
     * Move URL to list of processed URLs and update job step to indicate progress
99
     * indication of progress is important for jobs which take long time to process
100
     * jobs that do not indicate progress may be identified as stalled by the queue
101
     * and may end up paused
102
     *
103
     * @param string $url
104
     */
105
    protected function markUrlAsProcessed(string $url): void
106
    {
107
        // These operation has to be done directly on the job data properties
108
        // as the magic methods won't cover array access write
109
        $this->jobData->ProcessedURLs[$url] = $url;
110
        unset($this->jobData->URLsToProcess[$url]);
111
        $this->currentStep += 1;
112
    }
113
114
    /**
115
     * Check if job is complete and update the job state if needed
116
     */
117
    protected function updateCompletedState(): void
118
    {
119
        if (count($this->URLsToProcess) > 0) {
120
            return;
121
        }
122
123
        $this->isComplete = true;
124
    }
125
126
    /**
127
     * @return int
128
     */
129
    protected function getChunkSize(): int
130
    {
131
        $chunkSize = (int) $this->config()->get('chunk_size');
132
133
        return $chunkSize > 0 ? $chunkSize : 0;
134
    }
135
136
    /**
137
     * This function can be overridden to handle the case of failure of specific URL processing
138
     * such case is not handled by default which results in all such errors being effectively silenced
139
     *
140
     * @param string $url
141
     * @param array $meta
142
     */
143
    protected function handleFailedUrl(string $url, array $meta)
144
    {
145
        // no op - override this on your job classes if needed
146
    }
147
}
148