Completed
Push — master ( 2c00e3...367d56 )
by Peter
05:32
created

PredisUniqueCommandQueue   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 5
lcom 1
cbo 2
dl 0
loc 76
ccs 18
cts 18
cp 1
rs 10
c 1
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A push() 0 9 1
A pop() 0 21 3
1
<?php
2
3
/**
4
 * GpsLab component.
5
 *
6
 * @author    Peter Gribanov <[email protected]>
7
 * @copyright Copyright (c) 2011, Peter Gribanov
8
 * @license   http://opensource.org/licenses/MIT
9
 */
10
11
namespace GpsLab\Component\Command\Queue;
12
13
use GpsLab\Component\Command\Command;
14
use Predis\Client;
15
use Psr\Log\LoggerInterface;
16
use Symfony\Component\Serializer\SerializerInterface;
17
18
class PredisUniqueCommandQueue implements CommandQueue
19
{
20
    const LIST_KEY = 'unique_commands';
21
    const FORMAT = PredisCommandQueue::FORMAT;
22
23
    /**
24
     * @var Client
25
     */
26
    private $client;
27
28
    /**
29
     * @var SerializerInterface
30
     */
31
    private $serializer;
32
33
    /**
34
     * @var LoggerInterface
35
     */
36
    private $logger;
37
38
    /**
39
     * @param Client              $client
40
     * @param SerializerInterface $serializer
41
     * @param LoggerInterface     $logger
42
     */
43 3
    public function __construct(Client $client, SerializerInterface $serializer, LoggerInterface $logger)
44
    {
45 3
        $this->client = $client;
46 3
        $this->serializer = $serializer;
47 3
        $this->logger = $logger;
48 3
    }
49
50
    /**
51
     * Push command to queue.
52
     *
53
     * @param Command $command
54
     *
55
     * @return bool
56
     */
57 1
    public function push(Command $command)
58
    {
59 1
        $value = $this->serializer->serialize($command, self::FORMAT);
60
61
        // remove exists command and push it again
62 1
        $this->client->lrem(self::LIST_KEY, 0, $value);
63
64 1
        return (bool) $this->client->rpush(self::LIST_KEY, [$value]);
65
    }
66
67
    /**
68
     * Pop command from queue. Return NULL if queue is empty.
69
     *
70
     * @return Command|null
71
     */
72 2
    public function pop()
73
    {
74 2
        $value = $this->client->lpop(self::LIST_KEY);
75
76 2
        if (!$value) {
77 1
            return null;
78
        }
79
80
        try {
81 2
            return $this->serializer->deserialize($value, Command::class, self::FORMAT);
82 1
        } catch (\Exception $e) {
83
            // it's a critical error
84
            // it is necessary to react quickly to it
85 1
            $this->logger->critical('Failed denormalize a command in the Redis queue', [$value, $e->getMessage()]);
86
87
            // try denormalize in later
88 1
            $this->client->rpush(self::LIST_KEY, [$value]);
89
90 1
            return null;
91
        }
92
    }
93
}
94