Skip to content

Commit

Permalink
Add support for releasing lock again
Browse files Browse the repository at this point in the history
  • Loading branch information
Oliver committed Oct 27, 2022
1 parent 49e1ea1 commit ae342bc
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 12 deletions.
7 changes: 7 additions & 0 deletions src/Illuminate/Console/CacheCommandMutex.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ public function exists($command)
);
}

public function release($command)
{
return $this->cache->store($this->store)->forget(
$this->commandMutexName($command)
);
}

/**
* @param Command $command
* @return string
Expand Down
17 changes: 15 additions & 2 deletions src/Illuminate/Console/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public function run(InputInterface $input, OutputInterface $output): int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
if ($this instanceof Isolated && ! $this->laravel->get(CommandMutex::class)->create($this)) {
if ($this instanceof Isolated && ! $this->mutex()->create($this)) {
$this->info(sprintf(
'Skipping [%s], as command already running.', $this->getName()
));
Expand All @@ -150,7 +150,20 @@ protected function execute(InputInterface $input, OutputInterface $output)

$method = method_exists($this, 'handle') ? 'handle' : '__invoke';

return (int) $this->laravel->call([$this, $method]);
try {
return (int) $this->laravel->call([$this, $method]);
} finally {
if ($this instanceof Isolated) {
$this->mutex()->release($this);
}
}
}

protected function mutex()
{
return $this->laravel->bound(CommandMutex::class)
? $this->laravel->make(CommandMutex::class)
: $this->laravel->make(CacheCommandMutex::class);
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/Illuminate/Console/CommandMutex.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ interface CommandMutex
*/
public function create($command);

/**
* Release the mutex for the given command.
*
* @param Command $command
* @return bool
*/
public function release($command);

/**
* Determine if a command mutex exists for the given command.
*
Expand Down
46 changes: 36 additions & 10 deletions tests/Console/CommandMutexTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ protected function setUp(): void
{
$this->command = new class extends Command implements Isolated
{
public bool $ran = false;
public $ran = 0;

public function __invoke()
{
$this->ran = true;
$this->ran++;
}
};

Expand All @@ -46,23 +46,49 @@ public function __invoke()

public function testCanRunIsolatedCommandIfNotBlocked()
{
$this->commandMutex->shouldReceive('create')->andReturn(true);
$this->commandMutex->shouldReceive('create')
->andReturn(true)
->once();
$this->commandMutex->shouldReceive('release')
->andReturn(true)
->once();

$input = new ArrayInput([]);
$output = new NullOutput;
$this->command->run($input, $output);
$this->runCommand();

$this->assertTrue($this->command->ran);
$this->assertEquals(1, $this->command->ran);
}

public function testCannotRunIsolatedCommandIfBlocked()
{
$this->commandMutex->shouldReceive('create')->andReturn(false);
$this->commandMutex->shouldReceive('create')
->andReturn(false)
->once();

$this->runCommand();

$this->assertEquals(0, $this->command->ran);
}

public function testCanRunCommandAgainAfterOtherCommandFinished()
{
$this->commandMutex->shouldReceive('create')
->andReturn(true)
->twice();
$this->commandMutex->shouldReceive('release')
->andReturn(true)
->twice();

$this->runCommand();
$this->runCommand();

$this->assertEquals(2, $this->command->ran);
}


protected function runCommand()
{
$input = new ArrayInput([]);
$output = new NullOutput;
$this->command->run($input, $output);

$this->assertFalse($this->command->ran);
}
}

0 comments on commit ae342bc

Please sign in to comment.