Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Queue\Middleware;
4
 
5
use Illuminate\Container\Container;
6
use Illuminate\Contracts\Redis\Factory as Redis;
7
use Illuminate\Redis\Limiters\DurationLimiter;
8
use Illuminate\Support\InteractsWithTime;
9
 
10
class RateLimitedWithRedis extends RateLimited
11
{
12
    use InteractsWithTime;
13
 
14
    /**
15
     * The Redis factory implementation.
16
     *
17
     * @var \Illuminate\Contracts\Redis\Factory
18
     */
19
    protected $redis;
20
 
21
    /**
22
     * The timestamp of the end of the current duration by key.
23
     *
24
     * @var array
25
     */
26
    public $decaysAt = [];
27
 
28
    /**
29
     * Create a new middleware instance.
30
     *
31
     * @param  string  $limiterName
32
     * @return void
33
     */
34
    public function __construct($limiterName)
35
    {
36
        parent::__construct($limiterName);
37
 
38
        $this->redis = Container::getInstance()->make(Redis::class);
39
    }
40
 
41
    /**
42
     * Handle a rate limited job.
43
     *
44
     * @param  mixed  $job
45
     * @param  callable  $next
46
     * @param  array  $limits
47
     * @return mixed
48
     */
49
    protected function handleJob($job, $next, array $limits)
50
    {
51
        foreach ($limits as $limit) {
52
            if ($this->tooManyAttempts($limit->key, $limit->maxAttempts, $limit->decayMinutes)) {
53
                return $this->shouldRelease
54
                    ? $job->release($this->getTimeUntilNextRetry($limit->key))
55
                    : false;
56
            }
57
        }
58
 
59
        return $next($job);
60
    }
61
 
62
    /**
63
     * Determine if the given key has been "accessed" too many times.
64
     *
65
     * @param  string  $key
66
     * @param  int  $maxAttempts
67
     * @param  int  $decayMinutes
68
     * @return bool
69
     */
70
    protected function tooManyAttempts($key, $maxAttempts, $decayMinutes)
71
    {
72
        $limiter = new DurationLimiter(
73
            $this->redis, $key, $maxAttempts, $decayMinutes * 60
74
        );
75
 
76
        return tap(! $limiter->acquire(), function () use ($key, $limiter) {
77
            $this->decaysAt[$key] = $limiter->decaysAt;
78
        });
79
    }
80
 
81
    /**
82
     * Get the number of seconds that should elapse before the job is retried.
83
     *
84
     * @param  string  $key
85
     * @return int
86
     */
87
    protected function getTimeUntilNextRetry($key)
88
    {
89
        return ($this->decaysAt[$key] - $this->currentTime()) + 3;
90
    }
91
 
92
    /**
93
     * Prepare the object after unserialization.
94
     *
95
     * @return void
96
     */
97
    public function __wakeup()
98
    {
99
        parent::__wakeup();
100
 
101
        $this->redis = Container::getInstance()->make(Redis::class);
102
    }
103
}