Completed
Push — master ( 2250ba...aafcaa )
by Kanto
28s queued 11s
created

LockManager   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 46
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 46
rs 10
wmc 6

4 Methods

Rating   Name   Duplication   Size   Complexity  
A unlock() 0 4 2
A isLock() 0 3 2
A lock() 0 3 1
A __construct() 0 4 1
1
<?php
2
/**
3
 * Kore : Simple And Minimal Framework
4
 *
5
 */
6
7
namespace Kore;
8
9
use Kore\Log;
10
11
/**
12
 * Command class
13
 *
14
 */
15
abstract class Command
16
{
17
    /**
18
     * command namespace
19
     *
20
     * @var string
21
     */
22
    protected $command;
23
    /**
24
     * command arguments
25
     *
26
     * @var array<string>
27
     */
28
    protected $args = array();
29
    /**
30
     * command options
31
     *
32
     * @var array<string>
33
     */
34
    protected $opts = array();
35
36
    /**
37
     * Processing Execution
38
     *
39
     * The process is implemented in subclasses.
40
     * @return void
41
     */
42
    abstract protected function exec();
43
    
44
    /**
45
     * Main Processing
46
     *
47
     * @param string $command command namespace
48
     * @param array<string> $args command arguments
49
     * @param array<string> $opts command options
50
     * @return void
51
     */
52
    public function main($command, $args, $opts)
53
    {
54
        $this->command = $command;
55
        $this->args = $args;
56
        $this->opts = $opts;
57
        Log::init($this->commandName(), $this->logLevel());
58
59
        $lockManager = new LockManager($this->commandName(), $this->lockTime());
60
        if ($lockManager->isLock()) {
61
            Log::warn('Process is running!');
62
            return;
63
        }
64
        $lockManager->lock();
65
66
        Log::debug(sprintf('[START]%s', $this->command));
67
        try {
68
            $this->exec();
69
        } catch (\Exception $e) {
70
            $lockManager->unlock();
71
            $this->handleError($e);
72
        }
73
        Log::debug(sprintf('[END]%s', $this->command));
74
75
        $lockManager->unlock();
76
    }
77
78
    /**
79
     * Get the command name
80
     *
81
     * The default is the end of the command namespace.
82
     * If you need to customize, please override it with subclasses.
83
     * @return string command name
84
     */
85
    protected function commandName()
86
    {
87
        $namespace = explode('\\', $this->command);
88
        return $namespace[count($namespace) - 1];
89
    }
90
91
    /**
92
     * Get the log level
93
     *
94
     * The default is Log::LEVEL_DEBUG.
95
     * If you need to customize, please override it with subclasses.
96
     * @return int log level
97
     * @see \Kore\Log
98
     */
99
    protected function logLevel()
100
    {
101
        return Log::LEVEL_DEBUG;
102
    }
103
104
    /**
105
     * Get the lock time
106
     *
107
     * The default is 24 hours.
108
     * If you need to customize, please override it with subclasses.
109
     * @return int lock time
110
     */
111
    protected function lockTime()
112
    {
113
        return 60 * 60 * 24;
114
    }
115
116
    /**
117
     * Handling Errors
118
     *
119
     * If you need to customize the handling of errors, please override it with subclasses.
120
     * @param \Exception $e errors
121
     * @return void
122
     * @throws \Exception
123
     */
124
    protected function handleError($e)
125
    {
126
        Log::error($e->getMessage());
127
        throw $e;
128
    }
129
130
    /**
131
     * Get the command arguments
132
     *
133
     * If no key is specified, all command arguments are returned.
134
     * @param string|null $key command arguments key
135
     * @param mixed $default default value if there is no value specified in the key
136
     * @return string|array<string>|null command arguments
137
     */
138
    protected function getArg($key = null, $default = null)
139
    {
140
        if ($key === null) {
141
            return $this->args;
142
        }
143
        if (!isset($this->args[$key])) {
144
            return $default;
145
        }
146
        return $this->args[$key];
147
    }
148
149
    /**
150
     * Get the command options
151
     *
152
     * If no key is specified, all command options are returned.
153
     * @param string|null $key command options key
154
     * @param mixed $default default value if there is no value specified in the key
155
     * @return string|array<string>|null command options
156
     */
157
    protected function getOpt($key = null, $default = null)
158
    {
159
        if ($key === null) {
160
            return $this->opts;
161
        }
162
        if (!isset($this->opts[$key])) {
163
            return $default;
164
        }
165
        return $this->opts[$key];
166
    }
167
}
168
169
/**
170
 * Managing Command Lock
171
 *
172
 */
173
class LockManager
174
{
175
    /** @var string lock file */
176
    private $lockFile;
177
    /** @var int lock time */
178
    private $lockTime;
179
180
    /**
181
     * __construct
182
     * @param string $lockFileName lock file name
183
     * @param int $lockTime lock time
184
     * @return void
185
     */
186
    public function __construct($lockFileName, $lockTime)
187
    {
188
        $this->lockFile = TMP_DIR.'/'.$lockFileName.'.lock';
189
        $this->lockTime = $lockTime;
190
    }
191
192
    /**
193
     * Lock
194
     * @return void
195
     */
196
    public function lock()
197
    {
198
        touch($this->lockFile);
199
    }
200
201
    /**
202
     * Unlock
203
     * @return void
204
     */
205
    public function unlock()
206
    {
207
        if (file_exists($this->lockFile)) {
208
            unlink($this->lockFile);
209
        }
210
    }
211
212
    /**
213
     * Locked or not
214
     * @return boolean locked or not
215
     */
216
    public function isLock()
217
    {
218
        return file_exists($this->lockFile) && filemtime($this->lockFile) + $this->lockTime >= time();
219
    }
220
}
221