vendor and env first commit

This commit is contained in:
2025-03-28 08:52:46 +01:00
parent f8388bc81b
commit 8f26283832
10976 changed files with 1349952 additions and 2 deletions
@@ -0,0 +1,146 @@
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Cache\RateLimiter;
use Illuminate\Cache\RateLimiting\Unlimited;
use Illuminate\Container\Container;
use Illuminate\Support\Arr;
class RateLimited
{
/**
* The rate limiter instance.
*
* @var \Illuminate\Cache\RateLimiter
*/
protected $limiter;
/**
* The name of the rate limiter.
*
* @var string
*/
protected $limiterName;
/**
* Indicates if the job should be released if the limit is exceeded.
*
* @var bool
*/
public $shouldRelease = true;
/**
* Create a new middleware instance.
*
* @param string $limiterName
* @return void
*/
public function __construct($limiterName)
{
$this->limiter = Container::getInstance()->make(RateLimiter::class);
$this->limiterName = $limiterName;
}
/**
* Process the job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
if (is_null($limiter = $this->limiter->limiter($this->limiterName))) {
return $next($job);
}
$limiterResponse = $limiter($job);
if ($limiterResponse instanceof Unlimited) {
return $next($job);
}
return $this->handleJob(
$job,
$next,
collect(Arr::wrap($limiterResponse))->map(function ($limit) {
return (object) [
'key' => md5($this->limiterName.$limit->key),
'maxAttempts' => $limit->maxAttempts,
'decaySeconds' => $limit->decaySeconds,
];
})->all()
);
}
/**
* Handle a rate limited job.
*
* @param mixed $job
* @param callable $next
* @param array $limits
* @return mixed
*/
protected function handleJob($job, $next, array $limits)
{
foreach ($limits as $limit) {
if ($this->limiter->tooManyAttempts($limit->key, $limit->maxAttempts)) {
return $this->shouldRelease
? $job->release($this->getTimeUntilNextRetry($limit->key))
: false;
}
$this->limiter->hit($limit->key, $limit->decaySeconds);
}
return $next($job);
}
/**
* Do not release the job back to the queue if the limit is exceeded.
*
* @return $this
*/
public function dontRelease()
{
$this->shouldRelease = false;
return $this;
}
/**
* Get the number of seconds that should elapse before the job is retried.
*
* @param string $key
* @return int
*/
protected function getTimeUntilNextRetry($key)
{
return $this->limiter->availableIn($key) + 3;
}
/**
* Prepare the object for serialization.
*
* @return array
*/
public function __sleep()
{
return [
'limiterName',
'shouldRelease',
];
}
/**
* Prepare the object after unserialization.
*
* @return void
*/
public function __wakeup()
{
$this->limiter = Container::getInstance()->make(RateLimiter::class);
}
}
@@ -0,0 +1,103 @@
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Container\Container;
use Illuminate\Contracts\Redis\Factory as Redis;
use Illuminate\Redis\Limiters\DurationLimiter;
use Illuminate\Support\InteractsWithTime;
class RateLimitedWithRedis extends RateLimited
{
use InteractsWithTime;
/**
* The Redis factory implementation.
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
/**
* The timestamp of the end of the current duration by key.
*
* @var array
*/
public $decaysAt = [];
/**
* Create a new middleware instance.
*
* @param string $limiterName
* @return void
*/
public function __construct($limiterName)
{
parent::__construct($limiterName);
$this->redis = Container::getInstance()->make(Redis::class);
}
/**
* Handle a rate limited job.
*
* @param mixed $job
* @param callable $next
* @param array $limits
* @return mixed
*/
protected function handleJob($job, $next, array $limits)
{
foreach ($limits as $limit) {
if ($this->tooManyAttempts($limit->key, $limit->maxAttempts, $limit->decaySeconds)) {
return $this->shouldRelease
? $job->release($this->getTimeUntilNextRetry($limit->key))
: false;
}
}
return $next($job);
}
/**
* Determine if the given key has been "accessed" too many times.
*
* @param string $key
* @param int $maxAttempts
* @param int $decaySeconds
* @return bool
*/
protected function tooManyAttempts($key, $maxAttempts, $decaySeconds)
{
$limiter = new DurationLimiter(
$this->redis, $key, $maxAttempts, $decaySeconds
);
return tap(! $limiter->acquire(), function () use ($key, $limiter) {
$this->decaysAt[$key] = $limiter->decaysAt;
});
}
/**
* Get the number of seconds that should elapse before the job is retried.
*
* @param string $key
* @return int
*/
protected function getTimeUntilNextRetry($key)
{
return ($this->decaysAt[$key] - $this->currentTime()) + 3;
}
/**
* Prepare the object after unserialization.
*
* @return void
*/
public function __wakeup()
{
parent::__wakeup();
$this->redis = Container::getInstance()->make(Redis::class);
}
}
@@ -0,0 +1,22 @@
<?php
namespace Illuminate\Queue\Middleware;
class SkipIfBatchCancelled
{
/**
* Process the job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
if (method_exists($job, 'batch') && $job->batch()?->cancelled()) {
return;
}
$next($job);
}
}
@@ -0,0 +1,225 @@
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Cache\RateLimiter;
use Illuminate\Container\Container;
use Throwable;
class ThrottlesExceptions
{
/**
* The developer specified key that the rate limiter should use.
*
* @var string
*/
protected $key;
/**
* Indicates whether the throttle key should use the job's UUID.
*
* @var bool
*/
protected $byJob = false;
/**
* The maximum number of attempts allowed before rate limiting applies.
*
* @var int
*/
protected $maxAttempts;
/**
* The number of seconds until the maximum attempts are reset.
*
* @var int
*/
protected $decaySeconds;
/**
* The number of minutes to wait before retrying the job after an exception.
*
* @var int
*/
protected $retryAfterMinutes = 0;
/**
* The callback that determines if the exception should be reported.
*
* @var callable
*/
protected $reportCallback;
/**
* The callback that determines if rate limiting should apply.
*
* @var callable
*/
protected $whenCallback;
/**
* The prefix of the rate limiter key.
*
* @var string
*/
protected $prefix = 'laravel_throttles_exceptions:';
/**
* The rate limiter instance.
*
* @var \Illuminate\Cache\RateLimiter
*/
protected $limiter;
/**
* Create a new middleware instance.
*
* @param int $maxAttempts
* @param int $decaySeconds
* @return void
*/
public function __construct($maxAttempts = 10, $decaySeconds = 600)
{
$this->maxAttempts = $maxAttempts;
$this->decaySeconds = $decaySeconds;
}
/**
* Process the job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
$this->limiter = Container::getInstance()->make(RateLimiter::class);
if ($this->limiter->tooManyAttempts($jobKey = $this->getKey($job), $this->maxAttempts)) {
return $job->release($this->getTimeUntilNextRetry($jobKey));
}
try {
$next($job);
$this->limiter->clear($jobKey);
} catch (Throwable $throwable) {
if ($this->whenCallback && ! call_user_func($this->whenCallback, $throwable)) {
throw $throwable;
}
if ($this->reportCallback && call_user_func($this->reportCallback, $throwable)) {
report($throwable);
}
$this->limiter->hit($jobKey, $this->decaySeconds);
return $job->release($this->retryAfterMinutes * 60);
}
}
/**
* Specify a callback that should determine if rate limiting behavior should apply.
*
* @param callable $callback
* @return $this
*/
public function when(callable $callback)
{
$this->whenCallback = $callback;
return $this;
}
/**
* Set the prefix of the rate limiter key.
*
* @param string $prefix
* @return $this
*/
public function withPrefix(string $prefix)
{
$this->prefix = $prefix;
return $this;
}
/**
* Specify the number of minutes a job should be delayed when it is released (before it has reached its max exceptions).
*
* @param int $backoff
* @return $this
*/
public function backoff($backoff)
{
$this->retryAfterMinutes = $backoff;
return $this;
}
/**
* Get the cache key associated for the rate limiter.
*
* @param mixed $job
* @return string
*/
protected function getKey($job)
{
if ($this->key) {
return $this->prefix.$this->key;
} elseif ($this->byJob) {
return $this->prefix.$job->job->uuid();
}
return $this->prefix.md5(get_class($job));
}
/**
* Set the value that the rate limiter should be keyed by.
*
* @param string $key
* @return $this
*/
public function by($key)
{
$this->key = $key;
return $this;
}
/**
* Indicate that the throttle key should use the job's UUID.
*
* @return $this
*/
public function byJob()
{
$this->byJob = true;
return $this;
}
/**
* Report exceptions and optionally specify a callback that determines if the exception should be reported.
*
* @param callable|null $callback
* @return $this
*/
public function report(?callable $callback = null)
{
$this->reportCallback = $callback ?? fn () => true;
return $this;
}
/**
* Get the number of seconds that should elapse before the job is retried.
*
* @param string $key
* @return int
*/
protected function getTimeUntilNextRetry($key)
{
return $this->limiter->availableIn($key) + 3;
}
}
@@ -0,0 +1,66 @@
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Container\Container;
use Illuminate\Contracts\Redis\Factory as Redis;
use Illuminate\Redis\Limiters\DurationLimiter;
use Illuminate\Support\InteractsWithTime;
use Throwable;
class ThrottlesExceptionsWithRedis extends ThrottlesExceptions
{
use InteractsWithTime;
/**
* The Redis factory implementation.
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
/**
* The rate limiter instance.
*
* @var \Illuminate\Redis\Limiters\DurationLimiter
*/
protected $limiter;
/**
* Process the job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
$this->redis = Container::getInstance()->make(Redis::class);
$this->limiter = new DurationLimiter(
$this->redis, $this->getKey($job), $this->maxAttempts, $this->decaySeconds
);
if ($this->limiter->tooManyAttempts()) {
return $job->release($this->limiter->decaysAt - $this->currentTime());
}
try {
$next($job);
$this->limiter->clear();
} catch (Throwable $throwable) {
if ($this->whenCallback && ! call_user_func($this->whenCallback, $throwable)) {
throw $throwable;
}
if ($this->reportCallback && call_user_func($this->reportCallback, $throwable)) {
report($throwable);
}
$this->limiter->acquire();
return $job->release($this->retryAfterMinutes * 60);
}
}
}
@@ -0,0 +1,162 @@
<?php
namespace Illuminate\Queue\Middleware;
use Illuminate\Container\Container;
use Illuminate\Contracts\Cache\Repository as Cache;
use Illuminate\Support\InteractsWithTime;
class WithoutOverlapping
{
use InteractsWithTime;
/**
* The job's unique key used for preventing overlaps.
*
* @var string
*/
public $key;
/**
* The number of seconds before a job should be available again if no lock was acquired.
*
* @var \DateTimeInterface|int|null
*/
public $releaseAfter;
/**
* The number of seconds before the lock should expire.
*
* @var int
*/
public $expiresAfter;
/**
* The prefix of the lock key.
*
* @var string
*/
public $prefix = 'laravel-queue-overlap:';
/**
* Share the key across different jobs.
*
* @var bool
*/
public $shareKey = false;
/**
* Create a new middleware instance.
*
* @param string $key
* @param \DateTimeInterface|int|null $releaseAfter
* @param \DateTimeInterface|int $expiresAfter
* @return void
*/
public function __construct($key = '', $releaseAfter = 0, $expiresAfter = 0)
{
$this->key = $key;
$this->releaseAfter = $releaseAfter;
$this->expiresAfter = $this->secondsUntil($expiresAfter);
}
/**
* Process the job.
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
$lock = Container::getInstance()->make(Cache::class)->lock(
$this->getLockKey($job), $this->expiresAfter
);
if ($lock->get()) {
try {
$next($job);
} finally {
$lock->release();
}
} elseif (! is_null($this->releaseAfter)) {
$job->release($this->releaseAfter);
}
}
/**
* Set the delay (in seconds) to release the job back to the queue.
*
* @param \DateTimeInterface|int $releaseAfter
* @return $this
*/
public function releaseAfter($releaseAfter)
{
$this->releaseAfter = $releaseAfter;
return $this;
}
/**
* Do not release the job back to the queue if no lock can be acquired.
*
* @return $this
*/
public function dontRelease()
{
$this->releaseAfter = null;
return $this;
}
/**
* Set the maximum number of seconds that can elapse before the lock is released.
*
* @param \DateTimeInterface|\DateInterval|int $expiresAfter
* @return $this
*/
public function expireAfter($expiresAfter)
{
$this->expiresAfter = $this->secondsUntil($expiresAfter);
return $this;
}
/**
* Set the prefix of the lock key.
*
* @param string $prefix
* @return $this
*/
public function withPrefix(string $prefix)
{
$this->prefix = $prefix;
return $this;
}
/**
* Indicate that the lock key should be shared across job classes.
*
* @return $this
*/
public function shared()
{
$this->shareKey = true;
return $this;
}
/**
* Get the lock key for the given job.
*
* @param mixed $job
* @return string
*/
public function getLockKey($job)
{
return $this->shareKey
? $this->prefix.$this->key
: $this->prefix.get_class($job).':'.$this->key;
}
}