Issues (1)

php-src/Tasks/ASingleTask.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace kalanis\kw_clipr\Tasks;
4
5
6
use kalanis\kw_clipr\CliprException;
7
use kalanis\kw_locks\Interfaces\ILock;
8
use kalanis\kw_locks\Interfaces\IPassedKey;
9
use kalanis\kw_locks\LockException;
10
use kalanis\kw_locks\Methods\PidLock;
11
12
13
/**
14
 * Class ASingleTask
15
 * @package kalanis\kw_clipr\Tasks
16
 * @property bool $singleInstance
17
 */
18
abstract class ASingleTask extends ATask
19
{
20
    protected ILock $lock;
21
22
    /**
23
     * @param ILock|null $lock
24
     * @throws LockException
25
     */
26 7
    public function __construct(?ILock $lock = null)
27
    {
28 7
        $this->lock = $lock ?: $this->getPresetLock();
29 7
        if ($this->lock instanceof IPassedKey) {
30 2
            $this->lock->setKey(str_replace('/', ':', get_class($this)) . ILock::LOCK_FILE);
0 ignored issues
show
The method setKey() does not exist on kalanis\kw_locks\Interfaces\ILock. It seems like you code against a sub-type of kalanis\kw_locks\Interfaces\ILock such as kalanis\kw_locks\Interfaces\IPassedKey. ( Ignorable by Annotation )

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

30
            $this->lock->/** @scrutinizer ignore-call */ 
31
                         setKey(str_replace('/', ':', get_class($this)) . ILock::LOCK_FILE);
Loading history...
31 5
        } elseif (method_exists($this->lock, 'setClass')) {
32 1
            $this->lock->/** @scrutinizer ignore-call */setClass($this);
33
        }
34
        // lock target must go via lock's constructor
35
        // when it comes via IStorage (StorageLock), it's possible to connect it into Redis or Memcache and then that path might not be necessary
36 7
    }
37
38
    /**
39
     * @throws LockException
40
     * @return ILock
41
     */
42 1
    protected function getPresetLock(): ILock
43
    {
44 1
        return new PidLock($this->getTempPath());
45
    }
46
47 1
    protected function getTempPath(): string
48
    {
49 1
        return '/tmp';
50
    }
51
52
    /**
53
     * @throws CliprException
54
     */
55 4
    protected function startup(): void
56
    {
57 4
        parent::startup();
58 4
        $this->params->addParam('singleInstance', 'single-instance', null, false, 's', 'Call only single instance');
59
60 4
        $this->checkSingleInstance();
61 3
    }
62
63
    /**
64
     * @throws CliprException
65
     */
66 4
    protected function checkSingleInstance(): void
67
    {
68
        try {
69 4
            if ($this->isSingleInstance() && $this->isRunLocked()) {
70
                // check if exists another instance
71 3
                throw new SingleTaskException('One script instance is already running!', static::STATUS_ATTEMPT_LATER);
72
                // create own lock file
73
            }
74 2
        } catch (LockException $ex) {
75 1
            throw new SingleTaskException('Locked by another user. Cannot unlock here.', static::STATUS_PERMISSION_BLOCK, $ex);
76
        }
77 3
    }
78
79 4
    protected function isSingleInstance(): bool
80
    {
81 4
        return (true === $this->singleInstance);
82
    }
83
84
    /**
85
     * @throws LockException
86
     * @return bool
87
     */
88 4
    protected function isRunLocked(): bool
89
    {
90
        try {
91 4
            if (!$this->lock->has()) {
92 4
                $this->lock->create();
93 2
                return false;
94
            }
95 1
            return true;
96 2
        } catch (LockException $ex) {
97 2
            $this->writeLn('Removing stale lock file.');
98 2
            $this->lock->delete(true);
99 1
            return false;
100
        }
101
    }
102
}
103