Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pool.php - add methods to clear finished/results cache (#235) #237

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/Pool.php
Original file line number Diff line number Diff line change
Expand Up @@ -367,4 +367,15 @@ public function stop()
{
$this->stopped = true;
}

public function clearFinished()
{
$this->finished = [];
}

public function clearResults()
{
$this->results = [];
}

}
42 changes: 42 additions & 0 deletions tests/PoolTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,46 @@ public function it_writes_large_serialized_tasks_to_file()

$this->assertEquals(10, $counter, (string) $pool->status());
}

/** @test */
public function it_does_memory_footprint_controllable_by_clearing_results_issue_235()
{
$pool = Pool::create();
$this->assertEquals('queue: 0 - finished: 0 - failed: 0 - timeout: 0', trim($pool->status()->__toString()));
gc_collect_cycles();
$memUsageBefore = memory_get_usage();
$cntTasks = 30; // sane value to test, increasing above >500 takes a substantial time to test
foreach (range(1, $cntTasks) as $i) {
$pool->add(function () { return 1; });
}
$pool->wait();
$this->assertEquals('queue: 0 - finished: ' . $cntTasks . ' - failed: 0 - timeout: 0', trim($pool->status()->__toString()));
gc_collect_cycles();
$memUsageAfter1000Tasks = memory_get_usage();
$etaTaskMemFootprint = ($memUsageAfter1000Tasks - $memUsageBefore) / $cntTasks;
$pool->clearResults();
$pool->clearFinished();
$this->assertEquals('queue: 0 - finished: 0 - failed: 0 - timeout: 0', trim($pool->status()->__toString()));
gc_collect_cycles();
$memUsageAfter1000TasksWiped = memory_get_usage();
$etaTaskMemFootprintWiped = ($memUsageAfter1000TasksWiped - $memUsageBefore) / $cntTasks;
// dd($etaTaskMemFootprint . ' bytes --> ' . $etaTaskMemFootprintWiped . ' bytes per task');

/**
* tested with 1 tasks: "4928 bytes --> 824 bytes per task"
* tested with 10 tasks: "3769.6 bytes --> 114.4 bytes per task"
* tested with 100 tasks: "3678.08 bytes --> 17.84 bytes per task"
* tested with 300 tasks: "3939.4133333333 bytes --> 277.94666666667 bytes per task"
* tested with 600 tasks: "3970.9866666667 bytes --> 316.46666666667 bytes per task"
* tested with 600 tasks: "3970.9866666667 bytes --> 316.46666666667 bytes per task"
* tested with 10000 tasks: "3995.3432 bytes --> 351.176 bytes per task"
* the memory footprint of the results of one task is ~3-4KB
* eg: when one task is run every second, this yields a memory requirement of 3KB * 3600 * 24 = 260MB per day runtime
* When the result is wiped instead the memory footprint is (at least) an order of magnitude less, maybe even less / no mem leak at all.
*/
$this->assertTrue($etaTaskMemFootprint > 3000 && $etaTaskMemFootprint < 5000,
'memory footprint without wipe not as axpected, etaTaskMemFootprint: ' . $etaTaskMemFootprint);
$this->assertTrue($etaTaskMemFootprintWiped > 0 && $etaTaskMemFootprintWiped < 500,
'memory footprint with wipe not as axpected, etaTaskMemFootprintWiped: ' . $etaTaskMemFootprintWiped);
}
}