Skip to content

Commit

Permalink
Merge pull request #831 from themsaid/pr15030
Browse files Browse the repository at this point in the history
[4.x] Revert #820
  • Loading branch information
taylorotwell committed Apr 21, 2020
2 parents 2d3c94b + 726983b commit 03feeb6
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 109 deletions.
6 changes: 2 additions & 4 deletions src/MasterSupervisor.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,9 @@ public static function name()
*/
public static function basename()
{
$pathHash = substr(md5(__DIR__), 0, 4);

return static::$nameResolver
? call_user_func(static::$nameResolver).'-'.$pathHash
: Str::slug(gethostname()).'-'.$pathHash;
? call_user_func(static::$nameResolver)
: Str::slug(gethostname());
}

/**
Expand Down
56 changes: 10 additions & 46 deletions src/ProcessInspector.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public function __construct(Exec $exec)
*/
public function current()
{
$supervisorBasename = MasterSupervisor::basename();

return $this->exec->run("pgrep -f '[h]orizon.*[ =]{$supervisorBasename}-'");
return array_diff(
$this->exec->run('pgrep -f [h]orizon'),
$this->exec->run('pgrep -f horizon:purge')
);
}

/**
Expand All @@ -45,31 +46,17 @@ public function current()
*/
public function orphaned()
{
return array_diff(
array_merge($this->current(), $this->mastersWithoutSupervisors()),
$this->validMonitoring()
);
return array_diff($this->current(), $this->monitoring());
}

/**
* Get all of the process IDs that Horizon is actively monitoring and that are valid.
*
* For master processes "valid" means they have child processes (supervisors).
*
* For supervisors "valid" means their parent processes (masters) exist.
* Get all of the process IDs Horizon is actively monitoring.
*
* @return array
*/
public function validMonitoring()
public function monitoring()
{
$masters = $this->monitoredMastersWithSupervisors();

$masterNames = array_flip(Arr::pluck($masters, 'name'));

return collect(app(SupervisorRepository::class)->all())
->filter(function ($supervisor) use (&$masterNames) {
return isset($masterNames[data_get($supervisor, 'master')]);
})
->pluck('pid')
->pipe(function ($processes) {
$processes->each(function ($process) use (&$processes) {
Expand All @@ -78,31 +65,8 @@ public function validMonitoring()

return $processes;
})
->merge(Arr::pluck($masters, 'pid'))
->all();
}

/**
* Get the master processes that have child processes (supervisors) and are monitored by Horizon.
*
* @return array
*/
public function monitoredMastersWithSupervisors()
{
return collect(app(MasterSupervisorRepository::class)->all())->filter(function ($master) {
return ! empty($this->exec->run('pgrep -P '.data_get($master, 'pid')));
})->values()->all();
}

/**
* Get the IDs of all master Horizon processes that don't have any supervisors.
*
* @return array
*/
public function mastersWithoutSupervisors()
{
return collect($this->exec->run('pgrep -f [h]orizon$'))->filter(function ($pid) {
return empty($this->exec->run('pgrep -P '.$pid));
})->values()->all();
->merge(
Arr::pluck(app(MasterSupervisorRepository::class)->all(), 'pid')
)->all();
}
}
61 changes: 2 additions & 59 deletions tests/Feature/ProcessInspectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Laravel\Horizon\Contracts\MasterSupervisorRepository;
use Laravel\Horizon\Contracts\SupervisorRepository;
use Laravel\Horizon\Exec;
use Laravel\Horizon\MasterSupervisor;
use Laravel\Horizon\ProcessInspector;
use Laravel\Horizon\Tests\IntegrationTest;
use Mockery;
Expand All @@ -15,10 +14,8 @@ class ProcessInspectorTest extends IntegrationTest
public function test_finds_orphaned_process_ids()
{
$exec = Mockery::mock(Exec::class);
$exec->shouldReceive('run')->with(Mockery::pattern('/^pgrep -f \'\[h\]orizon\.\*\[ =\]/'))
->andReturn([1, 2, 3, 4, 5, 6]);
$exec->shouldReceive('run')->with('pgrep -f [h]orizon$')->andReturn([6]);
$exec->shouldReceive('run')->with('pgrep -P 6')->andReturn([2, 3]);
$exec->shouldReceive('run')->with('pgrep -f [h]orizon')->andReturn([1, 2, 3, 4, 5, 6]);
$exec->shouldReceive('run')->with('pgrep -f horizon:purge')->andReturn([]);
$exec->shouldReceive('run')->with('pgrep -P 2')->andReturn([4]);
$exec->shouldReceive('run')->with('pgrep -P 3')->andReturn([5]);
$this->app->instance(Exec::class, $exec);
Expand All @@ -27,11 +24,9 @@ public function test_finds_orphaned_process_ids()
$supervisors->shouldReceive('all')->andReturn([
[
'pid' => 2,
'master' => 'test',
],
[
'pid' => 3,
'master' => 'test',
],
]);
$this->app->instance(SupervisorRepository::class, $supervisors);
Expand All @@ -40,7 +35,6 @@ public function test_finds_orphaned_process_ids()
$masters->shouldReceive('all')->andReturn([
[
'pid' => 6,
'name' => 'test',
],
]);
$this->app->instance(MasterSupervisorRepository::class, $masters);
Expand All @@ -49,55 +43,4 @@ public function test_finds_orphaned_process_ids()

$this->assertEquals([1], $inspector->orphaned());
}

public function test_it_uses_master_supervisor_basename_to_find_current_processes()
{
$exec = Mockery::mock(Exec::class);
$this->app->instance(Exec::class, $exec);
$masterBasename = MasterSupervisor::basename();
$exec->shouldReceive('run')->with(Mockery::pattern("/pgrep -f '\[h\]orizon\.\*\[ =\].*{$masterBasename}-'/"))
->andReturn([1]);

$this->assertEquals([1], resolve(ProcessInspector::class)->current());
}

public function test_it_finds_monitored_masters_that_have_supervisor_processes()
{
$exec = Mockery::mock(Exec::class);
$this->app->instance(Exec::class, $exec);
$exec->shouldReceive('run')->with('pgrep -P 3')->andReturn([1, 2]);
$exec->shouldReceive('run')->with('pgrep -P 4')->andReturn([]);

$masters = Mockery::mock(MasterSupervisorRepository::class);
$this->app->instance(MasterSupervisorRepository::class, $masters);
$masters->shouldReceive('all')->andReturn([
[
'pid' => 3,
],
[
'pid' => 4,
],
]);

$inspector = resolve(ProcessInspector::class);

$this->assertEquals([
[
'pid' => 3,
],
], $inspector->monitoredMastersWithSupervisors());
}

public function test_it_finds_master_processes_without_supervisor_child_processes()
{
$exec = Mockery::mock(Exec::class);
$this->app->instance(Exec::class, $exec);
$exec->shouldReceive('run')->with('pgrep -f [h]orizon$')->andReturn([1, 2]);
$exec->shouldReceive('run')->with('pgrep -P 1')->andReturn([[3, 4]]);
$exec->shouldReceive('run')->with('pgrep -P 2')->andReturn([]);

$inspector = resolve(ProcessInspector::class);

$this->assertEquals([2], $inspector->mastersWithoutSupervisors());
}
}

0 comments on commit 03feeb6

Please sign in to comment.