Skip to content

Commit

Permalink
Merge branch '10.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
nunomaduro committed May 17, 2023
2 parents a7be8bf + 1719c36 commit 7cf552a
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 13 deletions.
33 changes: 33 additions & 0 deletions src/Illuminate/Queue/Events/JobTimedOut.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Illuminate\Queue\Events;

class JobTimedOut
{
/**
* The connection name.
*
* @var string
*/
public $connectionName;

/**
* The job instance.
*
* @var \Illuminate\Contracts\Queue\Job
*/
public $job;

/**
* Create a new event instance.
*
* @param string $connectionName
* @param \Illuminate\Contracts\Queue\Job $job
* @return void
*/
public function __construct($connectionName, $job)
{
$this->job = $job;
$this->connectionName = $connectionName;
}
}
5 changes: 5 additions & 0 deletions src/Illuminate/Queue/Worker.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Queue\Events\JobReleasedAfterException;
use Illuminate\Queue\Events\JobTimedOut;
use Illuminate\Queue\Events\Looping;
use Illuminate\Queue\Events\WorkerStopping;
use Illuminate\Support\Carbon;
Expand Down Expand Up @@ -223,6 +224,10 @@ protected function registerTimeoutHandler($job, WorkerOptions $options)
$this->markJobAsFailedIfItShouldFailOnTimeout(
$job->getConnectionName(), $job, $e
);

$this->events->dispatch(new JobTimedOut(
$job->getConnectionName(), $job
));
}

$this->kill(static::EXIT_ERROR, $options);
Expand Down
67 changes: 54 additions & 13 deletions src/Illuminate/Support/Sleep.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
use Carbon\Carbon;
use Carbon\CarbonInterval;
use DateInterval;
use Illuminate\Support\Traits\Macroable;
use PHPUnit\Framework\Assert as PHPUnit;
use RuntimeException;

class Sleep
{
use Macroable;

/**
* The total duration to sleep.
*
Expand Down Expand Up @@ -53,19 +56,7 @@ class Sleep
*/
public function __construct($duration)
{
if (! $duration instanceof DateInterval) {
$this->duration = CarbonInterval::microsecond(0);

$this->pending = $duration;
} else {
$duration = CarbonInterval::instance($duration);

if ($duration->totalMicroseconds < 0) {
$duration = CarbonInterval::seconds(0);
}

$this->duration = $duration;
}
$this->duration($duration);
}

/**
Expand Down Expand Up @@ -116,6 +107,32 @@ public static function sleep($duration)
return (new static($duration))->seconds();
}

/**
* Sleep for the given duration. Replaces any previously defined duration.
*
* @param \DateInterval|int|float $duration
* @return $this
*/
protected function duration($duration)
{
if (! $duration instanceof DateInterval) {
$this->duration = CarbonInterval::microsecond(0);

$this->pending = $duration;
} else {
$duration = CarbonInterval::instance($duration);

if ($duration->totalMicroseconds < 0) {
$duration = CarbonInterval::seconds(0);
}

$this->duration = $duration;
$this->pending = null;
}

return $this;
}

/**
* Sleep for the given number of minutes.
*
Expand Down Expand Up @@ -394,4 +411,28 @@ protected function shouldNotSleep()

return $this;
}

/**
* Only sleep when the given condition is true.
*
* @param (\Closure($this): bool)|bool $condition
* @return $this
*/
public function when($condition)
{
$this->shouldSleep = (bool) value($condition, $this);

return $this;
}

/**
* Don't sleep when the given condition is true.
*
* @param (\Closure($this): bool)|bool $condition
* @return $this
*/
public function unless($condition)
{
return $this->when(! value($condition, $this));
}
}
87 changes: 87 additions & 0 deletions tests/Support/SleepTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -414,4 +414,91 @@ public function testAssertSlept()
$this->assertSame("The expected sleep was found [0] times instead of [1].\nFailed asserting that 0 is identical to 1.", $e->getMessage());
}
}

public function testItCanCreateMacrosViaMacroable()
{
Sleep::fake();

Sleep::macro('forSomeConfiguredAmountOfTime', static function () {
return Sleep::for(3)->seconds();
});

Sleep::macro('useSomeOtherAmountOfTime', function () {
/** @var Sleep $this */
return $this->duration(1.234)->seconds();
});

Sleep::macro('andSomeMoreGranularControl', function () {
/** @var Sleep $this */
return $this->and(567)->microseconds();
});

// A static macro can be referenced
$sleep = Sleep::forSomeConfiguredAmountOfTime();
$this->assertSame($sleep->duration->totalMicroseconds, 3000000);

// A macro can specify a new duration
$sleep = $sleep->useSomeOtherAmountOfTime();
$this->assertSame($sleep->duration->totalMicroseconds, 1234000);

// A macro can supplement an existing duration
$sleep = $sleep->andSomeMoreGranularControl();
$this->assertSame($sleep->duration->totalMicroseconds, 1234567);
}

public function testItCanReplacePreviouslyDefinedDurations()
{
Sleep::fake();

Sleep::macro('setDuration', function ($duration) {
return $this->duration($duration);
});

$sleep = Sleep::for(1)->second();
$this->assertSame($sleep->duration->totalMicroseconds, 1000000);

$sleep->setDuration(2)->second();
$this->assertSame($sleep->duration->totalMicroseconds, 2000000);

$sleep->setDuration(500)->milliseconds();
$this->assertSame($sleep->duration->totalMicroseconds, 500000);
}

public function testItCanSleepConditionallyWhen()
{
Sleep::fake();

// Control test
Sleep::assertSlept(fn () => true, 0);
Sleep::for(1)->second();
Sleep::assertSlept(fn () => true, 1);
Sleep::fake();
Sleep::assertSlept(fn () => true, 0);

// Reset
Sleep::fake();

// Will not sleep if `when()` yields `false`
Sleep::for(1)->second()->when(false);
Sleep::for(1)->second()->when(fn () => false);

// Will not sleep if `unless()` yields `true`
Sleep::for(1)->second()->unless(true);
Sleep::for(1)->second()->unless(fn () => true);

// Finish 'do not sleep' tests - assert no sleeping occurred
Sleep::assertSlept(fn () => true, 0);

// Will sleep if `when()` yields `true`
Sleep::for(1)->second()->when(true);
Sleep::assertSlept(fn () => true, 1);
Sleep::for(1)->second()->when(fn () => true);
Sleep::assertSlept(fn () => true, 2);

// Will sleep if `unless()` yields `false`
Sleep::for(1)->second()->unless(false);
Sleep::assertSlept(fn () => true, 3);
Sleep::for(1)->second()->unless(fn () => false);
Sleep::assertSlept(fn () => true, 4);
}
}

0 comments on commit 7cf552a

Please sign in to comment.