SmallFilesQueueTransport::clear_consumed_keys()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
    namespace NokitaKaze\Queue;
4
5
    use NokitaKaze\Mutex\FileMutex;
6
7
    class SmallFilesQueueTransport extends AbstractQueueTransport {
8
        const SINGLE_FILE_DB_VERSION = 1;
9
10
        protected $_message_folder;
11
        protected $_queue_name;
12
        protected $_message_folder_subfolder_count = Queue::DefaultMessageFolderSubfolderCount;
13
        protected $_key_to_file = [];
14
        protected $_is_inotify_enabled;
15
        protected $_chunk_file_postfix = '';
16
17
        /**
18
         * @var iMessage[]
19
         */
20
        protected $_last_consumed_messages = [];
21
        /**
22
         * @var integer[] В keys список файлов, которые были прочитаны
23
         */
24
        protected $_consumed_filenames = [];
25
26
        /**
27
         * @param SmallFilesQueueConstructionSettings|object $settings
28
         *
29
         * @throws QueueException
30
         */
31
        function __construct($settings) {
32
            if (!isset($settings->message_folder)) {
33
                throw new QueueException('message_folder has not been set');
34
            }
35
            if (!isset($settings->name)) {
36
                throw new QueueException('name has not been set');
37
            }
38
            $this->_message_folder = $settings->message_folder;
39
            $this->_queue_name = $settings->name;
40
            if (isset($settings->message_folder_subfolder_count)) {
41
                $this->_message_folder_subfolder_count = $settings->message_folder_subfolder_count;
42
            }
43
            if (isset($settings->is_inotify_enabled)) {
44
                $this->_is_inotify_enabled = $settings->is_inotify_enabled;
45
            } else {
46
                $this->_is_inotify_enabled = function_exists('inotify_init');
47
            }
48
            $this->_chunk_file_postfix = '_'.static::generate_rnd_postfix();
49
        }
50
51
        /**
52
         * @param boolean $mode
53
         *
54
         * @hint Ничего не делаем, у этого транспорта нет эксклюзивного режима
55
         * @codeCoverageIgnore
56
         */
57
        function set_exclusive_mode($mode) { }
58
59
        /**
60
         * @return string
61
         */
62
        function get_queue_name() {
63
            return $this->_queue_name;
64
        }
65
66
        function save() {
67
            $this->set_same_time_flag(1);
68
            if (empty($this->_pushed_for_save)) {
69
                return;
70
            }
71
72
            /**
73
             * @var SmallFilesQueueSingleFile $data
74
             */
75
            $data = (object) [];
76
            $data->queue = $this->_pushed_for_save;
0 ignored issues
show
Bug introduced by
Accessing queue on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
77
            $data->queue_name = $this->_queue_name;
0 ignored issues
show
Bug introduced by
Accessing queue_name on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
78
            $data->time_create = microtime(true);
0 ignored issues
show
Bug introduced by
Accessing time_create on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
79
            $data->time_last_update = microtime(true);
0 ignored issues
show
Bug introduced by
Accessing time_last_update on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
80
            $data->version = self::SINGLE_FILE_DB_VERSION;
0 ignored issues
show
Bug introduced by
Accessing version on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
81
            $num = mt_rand(0, $this->_message_folder_subfolder_count - 1);
82
            $folder = $this->_message_folder.'/'.$num;
83
            FileMutex::create_folders_in_path($folder);
84
            $filename = sprintf('%s/smartqueue_%s%s.chunk.dat',
85
                $folder, number_format(microtime(true), 4, '.', ''), $this->_chunk_file_postfix);
86
87
            $u = file_put_contents($filename, Queue::serialize($data), LOCK_EX);
88
            if ($u === false) {
89
                // @codeCoverageIgnoreStart
90
                throw new QueueException('Can not save queue to a file: '.FileMutex::get_last_php_error_as_string());
91
                // @codeCoverageIgnoreEnd
92
            }
93
            foreach ($this->_pushed_for_save as $message) {
94
                $this->_key_to_file[static::get_real_key_for_message($message)] = $filename;
95
            }
96
            $this->_pushed_for_save = [];
97
        }
98
99
        /**
100
         * @param double|integer $wait_time
101
         *
102
         * @return iMessage|object|null
103
         * @throws QueueException
104
         */
105
        function consume_next_message($wait_time = -1) {
106
            $this->set_same_time_flag(2);
107
            if (!empty($this->_last_consumed_messages)) {
108
                return array_shift($this->_last_consumed_messages);
109
            }
110
111
            return $this->consume_next_message_without_inotify($wait_time);
112
            /*
113
            if ($this->_is_inotify_enabled and false) {// @todo добавить Inotify
114
                // @codeCoverageIgnoreStart
115
                return $this->consume_next_message_with_inotify($wait_time);
116
                // @codeCoverageIgnoreEnd
117
            } else {
118
                return $this->consume_next_message_without_inotify($wait_time);
119
            }
120
            */
121
        }
122
123
        function clear_consumed_keys() {
124
            parent::clear_consumed_keys();
125
            $this->_last_consumed_messages = [];
126
            $this->_consumed_filenames = [];
127
        }
128
129
        function __clone() {
130
            parent::__clone();
131
            foreach ($this->_last_consumed_messages as &$message) {
132
                $message = clone $message;
133
            }
134
        }
135
136
        /**
137
         * @param double|integer $wait_time
138
         *
139
         * @return iMessage|object|null
140
         */
141
        protected function consume_next_message_without_inotify($wait_time = -1) {
142
            $start = microtime(true);
143
            do {
144
                for ($i = 0; $i < $this->_message_folder_subfolder_count; $i++) {
145
                    $folder = $this->_message_folder.'/'.$i;
146
                    if (!file_exists($folder) or !is_readable($folder) or !is_dir($folder)) {
147
                        continue;
148
                    }
149
                    $event = $this->consume_next_message_without_inotify_folder($folder);
150
                    if (!is_null($event)) {
151
                        return $event;
152
                    }
153
                }
154
            } while (($wait_time == -1) or ($start + $wait_time >= microtime(true)));
155
156
            return null;
157
        }
158
159
        /**
160
         * @param string $folder
161
         *
162
         * @return iMessage|object|null
163
         */
164
        protected function consume_next_message_without_inotify_folder($folder) {
165
            foreach (scandir($folder) as $f) {
166
                if (in_array($f, ['.', '..']) or !preg_match('|smartqueue_[0-9.]+(_[a-z0-9]+)?\\.chunk\\.dat$|', $f)) {
167
                    continue;
168
                }
169
                $filename = $folder.'/'.$f;
170
                if (is_dir($filename) or !is_readable($filename)) {
171
                    continue;
172
                }
173
                $event = $this->consume_next_message_from_file($filename);
174
                if (!is_null($event)) {
175
                    return $event;
176
                }
177
            }
178
179
            return null;
180
        }
181
182
183
        /**
184
         * Забираем новые event'ы из файла. Файл должен быть уже существующим, читабельным
185
         *
186
         * Проверка на присутствие в индексе осуществляется в этом файле
187
         *
188
         * @param string $filename
189
         *
190
         * @return iMessage|object|null
191
         */
192
        protected function consume_next_message_from_file($filename) {
193
            if (isset($this->_consumed_filenames[$filename])) {
194
                return null;
195
            }
196
197
            $fi = fopen($filename, 'r');
198
            $locked = flock($fi, LOCK_EX | LOCK_NB);
199
            if (!$locked) {
200
                fclose($fi);
201
202
                return null;
203
            }
204
205
            $buf = file_get_contents($filename);
206
            /**
207
             * @var SmallFilesQueueSingleFile $file_data
208
             */
209
            $file_data = Queue::unserialize($buf, $is_valid);
210
            if (!is_object($file_data)) {
211
                // File does not contain Single Queue object
212
                flock($fi, LOCK_UN);
213
                fclose($fi);
214
215
                return null;
216
            }
217
            if ($file_data->queue_name != $this->get_queue_name()) {
218
                flock($fi, LOCK_UN);
219
                fclose($fi);
220
221
                return null;
222
            }
223
            if ($file_data->version != self::SINGLE_FILE_DB_VERSION) {
224
                flock($fi, LOCK_UN);
225
                fclose($fi);
226
227
                return null;
228
            }
229
230
            $this->_last_consumed_messages = [];
231
            foreach ($file_data->queue as $message) {
232
                $key = self::get_real_key_for_message($message);
233
                if (isset($this->_consumed_keys[$key])) {
234
                    continue;
235
                }
236
237
                $message->time_consumed = microtime(true);
238
                $message->queue = $this;
239
                $this->_key_to_file[$key] = $filename;
240
                $this->_last_consumed_messages[] = $message;
241
                $this->_consumed_keys[$key] = 1;
242
            }
243
            flock($fi, LOCK_UN);
244
            fclose($fi);
245
            $this->_consumed_filenames[$filename] = 1;
246
247
            return !empty($this->_last_consumed_messages) ? array_shift($this->_last_consumed_messages) : null;
248
        }
249
250
        /**
251
         * @param iMessage[]|object[] $messages
252
         */
253
        protected function copy_key_to_file_from_messages(array $messages) {
254
            foreach ($messages as $message) {
255
                if (isset($message->queue) and (get_class($message->queue) == self::class)) {
256
                    foreach ($message->queue->_key_to_file as $key => $filename) {
257
                        $this->_key_to_file[$key] = $filename;
258
                    }
259
                }
260
            }
261
        }
262
263
        /**
264
         * @param iMessage[]|object[] $messages
265
         *
266
         * @return array[]
267
         */
268
        protected function get_filenames_from_messages(array $messages) {
269
            $this->copy_key_to_file_from_messages($messages);
270
            $filenames = [];
271
            $filenames_contains_keys = [];
272
            foreach ($messages as $message) {
273
                $key = self::get_real_key_for_message($message);
274
                if (!isset($this->_key_to_file[$key])) {
275
                    continue;
276
                }
277
                $filename = $this->_key_to_file[$key];
278
                $filenames[] = $filename;
279
                if (!isset($filenames_contains_keys[$filename])) {
280
                    $filenames_contains_keys[$filename] = [];
281
                }
282
283
                $filenames_contains_keys[$filename][] = $key;
284
            }
285
286
            return [$filenames, $filenames_contains_keys];
287
        }
288
289
        /**
290
         * Удалить сообщения и сразу же записать это в БД
291
         *
292
         * @param iMessage[]|object[] $messages
293
         *
294
         * @return string[]|integer[]
295
         * @throws QueueException
296
         */
297
        function delete_messages(array $messages) {
298
            /**
299
             * @var string[][] $filenames_contains_keys
300
             * @var string[]   $filenames
301
             */
302
            list($filenames, $filenames_contains_keys) = $this->get_filenames_from_messages($messages);
303
            $filenames_contains_keys_all = [];
304
            foreach ($this->_key_to_file as $key => $filename) {
305
                if (isset($filenames_contains_keys_all[$filename])) {
306
                    $filenames_contains_keys_all[$filename][] = $key;
307
                } else {
308
                    $filenames_contains_keys_all[$filename] = [$key];
309
                }
310
            }
311
            unset($key, $filename);
312
313
            $deleted_keys = [];
314
            foreach ($filenames as $filename) {
315
                if (!file_exists($filename)) {
316
                    // @todo Надо подумать правильный ли это подход
317
                    // Тут будут все ключи, а не только те, которые надо было удалить
318
                    $deleted_keys = array_merge($deleted_keys, $filenames_contains_keys[$filename]);
319
                    continue;
320
                }
321
                if (!is_writable($filename)) {
322
                    throw new QueueException('Can not delete messages from read only files');
323
                }
324
                if (count($filenames_contains_keys[$filename]) == count($filenames_contains_keys_all[$filename])) {
325
                    // Нужно удалить все записи в файле, значит можно просто удалить файл целиком
326
                    if (!unlink($filename)) {
327
                        // @codeCoverageIgnoreStart
328
                        throw new QueueException('Can not delete file '.$filename.': '.
329
                                                 FileMutex::get_last_php_error_as_string());
330
                        // @codeCoverageIgnoreEnd
331
                    }
332
                    $deleted_keys = array_merge($deleted_keys, $filenames_contains_keys[$filename]);
333
                    continue;
334
                }
335
336
                $fo = fopen($filename, 'r');
337
                $locked = flock($fo, LOCK_EX);
338
                if (!$locked) {
339
                    fclose($fo);
340
                    throw new QueueException('Can not delete file '.$filename);
341
                }
342
                $buf = file_get_contents($filename);
343
                if (empty($buf)) {
344
                    flock($fo, LOCK_UN);
345
                    fclose($fo);
346
                    throw new QueueException('File "'.$filename.'" is empty');
347
                }
348
                /**
349
                 * @var SmallFilesQueueSingleFile $data
350
                 */
351
                $data = Queue::unserialize($buf, $is_valid);
352
                if (!is_object($data)) {
353
                    flock($fo, LOCK_UN);
354
                    fclose($fo);
355
                    throw new QueueException('File "'.$filename.'" does not contain Single Queue object');
356
                }
357
                if ($data->queue_name != $this->get_queue_name()) {
0 ignored issues
show
Bug introduced by
Accessing queue_name on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
358
                    flock($fo, LOCK_UN);
359
                    fclose($fo);
360
                    throw new QueueException('Invalid queue name ("'.$data->queue_name.
0 ignored issues
show
Bug introduced by
Accessing queue_name on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
361
                                             '" instead of "'.$this->get_queue_name().'")');
362
                }
363
                if ($data->version != self::SINGLE_FILE_DB_VERSION) {
0 ignored issues
show
Bug introduced by
Accessing version on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
364
                    flock($fo, LOCK_UN);
365
                    fclose($fo);
366
                    continue;
367
                }
368
                $data->time_last_update = microtime(true);
0 ignored issues
show
Bug introduced by
Accessing time_last_update on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
369
370
                $new_queue = [];
371
                foreach ($data->queue as $message) {
0 ignored issues
show
Bug introduced by
Accessing queue on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
372
                    $key = self::get_real_key_for_message($message);
373
                    if (!in_array($key, $filenames_contains_keys[$filename])) {
374
                        $message->is_read = true;
375
                        $new_queue[] = $message;
376
                    } else {
377
                        $deleted_keys[] = $key;
378
                    }
379
                }
380
                if (empty($new_queue)) {
381
                    // @hint На самом деле это невозможно
382
                    flock($fo, LOCK_UN);
383
                    fclose($fo);
384
                    if (!unlink($filename)) {
385
                        // @codeCoverageIgnoreStart
386
                        throw new QueueException('Can not delete file '.$filename.': '.
387
                                                 FileMutex::get_last_php_error_as_string());
388
                        // @codeCoverageIgnoreEnd
389
                    }
390
                    continue;
391
                }
392
                $data->queue = $new_queue;
0 ignored issues
show
Bug introduced by
Accessing queue on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
393
                $u = file_put_contents($filename, Queue::serialize($data));
394
                if ($u === false) {
395
                    // @codeCoverageIgnoreStart
396
                    throw new QueueException('Can not save single query file "'.$filename.'": '.
397
                                             FileMutex::get_last_php_error_as_string());
398
                    // @codeCoverageIgnoreEnd
399
                }
400
                flock($fo, LOCK_UN);
401
                fclose($fo);
402
            }
403
404
            return array_unique($deleted_keys);
405
        }
406
407
        /**
408
         * Обновляем сообщение и сразу же сохраняем всё
409
         *
410
         * Эта функция не рейзит ошибку, если сообщение не найдено
411
         *
412
         * @param iMessage|object $message
413
         * @param string|null     $key форсированно задаём ключ сообщения
414
         *
415
         * @return boolean
416
         * @throws QueueException
417
         */
418
        function update_message($message, $key = null) {
419
            $this_key = !is_null($key) ? $key : self::get_real_key_for_message($message);
420
421
            if (!isset($this->_key_to_file[$this_key])) {
422
                // Нет такого файла в списке
423
                return false;
424
            }
425
            $filename = $this->_key_to_file[$this_key];
426
            if (!file_exists($filename)) {
427
                return false;
428
            }
429
            if (!is_writable($filename)) {
430
                throw new QueueException('Can not update read only file');
431
            }
432
433
            $fo = fopen($filename, 'r');
434
            $locked = flock($fo, LOCK_EX);
435
            if (!$locked) {
436
                fclose($fo);
437
                throw new QueueException('Can not delete file '.$filename.': '.FileMutex::get_last_php_error_as_string());
438
            }
439
            $buf = file_get_contents($filename);
440
            if (empty($buf)) {
441
                flock($fo, LOCK_UN);
442
                fclose($fo);
443
                throw new QueueException('File "'.$filename.'" is empty');
444
            }
445
            // @todo обрабатывать ошибки
446
            /**
447
             * @var SmallFilesQueueSingleFile $data_in
448
             */
449
            $data_in = Queue::unserialize($buf, $is_valid);
450
            if (!is_object($data_in)) {
451
                flock($fo, LOCK_UN);
452
                fclose($fo);
453
                throw new QueueException('File "'.$filename.'" does not contain Single Queue object');
454
            }
455
            if ($data_in->version != self::SINGLE_FILE_DB_VERSION) {
0 ignored issues
show
Bug introduced by
Accessing version on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
456
                flock($fo, LOCK_UN);
457
                fclose($fo);
458
                throw new QueueException('Single DB File version mismatch ('.$data_in->version.
0 ignored issues
show
Bug introduced by
Accessing version on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
459
                                         ' instead of '.self::SINGLE_FILE_DB_VERSION.')');
460
            }
461
            if ($data_in->queue_name != $this->get_queue_name()) {
0 ignored issues
show
Bug introduced by
Accessing queue_name on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
462
                flock($fo, LOCK_UN);
463
                fclose($fo);
464
                throw new QueueException('Invalid queue name ("'.$data_in->queue_name.
0 ignored issues
show
Bug introduced by
Accessing queue_name on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
465
                                         '" instead of "'.$this->get_queue_name().'")');
466
            }
467
            $data_in->time_last_update = microtime(true);
0 ignored issues
show
Bug introduced by
Accessing time_last_update on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
468
469
            // Ищем то же сообщение и заменяем его
470
            $exists = $this->change_message_in_array($data_in->queue, $message, $this_key);
0 ignored issues
show
Bug introduced by
Accessing queue on the interface NokitaKaze\Queue\SmallFilesQueueSingleFile suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
471
            if ($exists) {
472
                $u = file_put_contents($filename, Queue::serialize($data_in));
473
                if ($u === false) {
474
                    // @codeCoverageIgnoreStart
475
                    throw new QueueException('Can not save single query file "'.$filename.'": '.
476
                                             FileMutex::get_last_php_error_as_string());
477
                    // @codeCoverageIgnoreEnd
478
                }
479
            }
480
            flock($fo, LOCK_UN);
481
            fclose($fo);
482
483
            return $exists;
484
        }
485
486
        /**
487
         * Поддерживает ли очередь сортировку event'ов при вставке
488
         *
489
         * @return boolean
490
         */
491
        static function is_support_sorted_events() {
492
            return false;
493
        }
494
495
        /*
496
         * @param double|integer $wait_time
497
         *
498
         * @return iMessage|object|null
499
         *
500
         * @throws QueueException
501
         * @codeCoverageIgnore
502
         /
503
        protected function consume_next_message_with_inotify($wait_time = -1) {
504
            $start = microtime(true);
505
            // @todo написать
506
            throw new QueueException('Не готово');
507
        }
508
        */
509
510
        /*
511
         * @codeCoverageIgnore
512
         /
513
        function test_inotify() {
514
            // @todo этого тут быть не должно
515
            $a = inotify_init();
516
        }
517
        */
518
519
        /**
520
         * @param SmallFilesQueueTransport $queue
521
         *
522
         * @return boolean
523
         */
524
        function is_equal_to($queue) {
525
            if (spl_object_hash($this) == spl_object_hash($queue)) {
526
                return true;
527
            }
528
            if (!parent::is_equal_to($queue)) {
529
                return false;
530
            }
531
532
            return (($queue->_message_folder == $this->_message_folder) and
533
                    ($queue->get_queue_name() == $this->get_queue_name()));
534
        }
535
    }
536
537
?>