DistributedExpiration   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 4
lcom 1
cbo 3
dl 0
loc 63
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A methodsAvailable() 0 4 1
A extensionHandles() 0 14 1
A distributeExpire() 0 19 2
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Cache
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Cache\Extension;
16
17
use Phossa2\Cache\CachePool;
18
use Phossa2\Event\Interfaces\EventInterface;
19
use Phossa2\Event\EventableExtensionAbstract;
20
use Phossa2\Cache\Interfaces\CacheItemExtendedInterface;
21
22
/**
23
 * DistributedExpiration
24
 *
25
 * Change expiration time by -5% to 5% to evenly distribute cache miss
26
 *
27
 * ```php
28
 * $ext = new DistributedExpiration([
29
 *     'distribution' => 30 // -3% to 3%
30
 * ]);
31
 *
32
 * // enable this ext
33
 * $cachePool->addExtension($ext);
34
 * ```
35
 *
36
 * @package Phossa2\Cache
37
 * @author  Hong Zhang <[email protected]>
38
 * @see     EventableExtensionAbstract
39
 * @version 2.0.1
40
 * @since   2.0.0 added
41
 * @since   2.0.1 moved to EventableExtensionAbstract
42
 */
43
class DistributedExpiration extends EventableExtensionAbstract
44
{
45
    /**
46
     * item expiration time distribution 5% (50/1000)
47
     *
48
     * @var    int
49
     * @access protected
50
     */
51
    protected $distribution = 50;
52
53
    /**
54
     * {@inheritDoc}
55
     */
56
    public function methodsAvailable()/*# : array */
57
    {
58
        return ['distributeExpire'];
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64
    protected function extensionHandles()/*# : array */
65
    {
66
        // change item expire before save or saveDeferred
67
        return [
68
            [
69
                'event'   => CachePool::EVENT_SAVE_BEFORE,
70
                'handler' => ['distributeExpire', 80]
71
            ],
72
            [
73
                'event'   => CachePool::EVENT_DEFER_BEFORE,
74
                'handler' => ['distributeExpire', 80]
75
            ]
76
        ];
77
    }
78
79
    /**
80
     * Evenly distribute the expiration time
81
     *
82
     * @param  EventInterface $event
83
     * @return bool
84
     * @access public
85
     */
86
    public function distributeExpire(EventInterface $event)/*# : bool */
87
    {
88
        $dist = $this->distribution;
89
        $item = $event->getParam('item');
90
91
        if ($item instanceof CacheItemExtendedInterface) {
92
            // expire ttl
93
            $ttl = $item->getExpiration()->getTimestamp() - time();
94
95
            // percentage
96
            $percent = (rand(0, $dist * 2) - $dist) * 0.001;
97
98
            // new expire ttl
99
            $new_ttl = (int) round($ttl + $ttl * $percent);
100
            $item->expiresAfter($new_ttl);
101
        }
102
103
        return true;
104
    }
105
}
106