-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace app\commands; | ||
|
||
use app\components\BackgroundJobProcessor; | ||
use yii\console\Controller; | ||
|
||
/** | ||
* Run background commends | ||
*/ | ||
class BackgroundJobController extends Controller | ||
{ | ||
private const MAX_EVENTS = 1000; | ||
private const MAX_RUNTIME_SECONDS = 600; | ||
private const MAX_MEMORY_USAGE = 64_000_000; | ||
|
||
/** | ||
* Runs the background job processor | ||
* | ||
* @throws \yii\db\Exception | ||
*/ | ||
public function actionRun(): void | ||
{ | ||
$processor = new BackgroundJobProcessor(\Yii::$app->getDb()); | ||
while (!$this->needsRestart($processor)) { | ||
$row = $processor->getJobAndSetStarted(); | ||
if ($row) { | ||
$processor->processRow($row); | ||
} else { | ||
usleep(100000); | ||
} | ||
|
||
file_put_contents('/tmp/memory_usage.log', memory_get_peak_usage() . "\n", FILE_APPEND); | ||
} | ||
} | ||
|
||
private function needsRestart(BackgroundJobProcessor $processor): bool | ||
{ | ||
return $processor->getProcessedEvents() >= self::MAX_EVENTS | ||
|| $processor->getRuntimeInSeconds() >= self::MAX_RUNTIME_SECONDS | ||
|| memory_get_peak_usage() >= self::MAX_MEMORY_USAGE; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace app\components; | ||
|
||
use yii\db\Connection; | ||
|
||
class BackgroundJobProcessor | ||
{ | ||
private Connection $connection; | ||
|
||
private int $processedEvents = 0; | ||
private \DateTimeImmutable $startedAt; | ||
|
||
public function __construct(Connection $connection) { | ||
$this->connection = $connection; | ||
$this->startedAt = new \DateTimeImmutable(); | ||
} | ||
|
||
public function getJobAndSetStarted(): ?array { | ||
$foundRow = null; | ||
|
||
$this->connection->transaction(function () use (&$foundRow) { | ||
$command = $this->connection->createCommand('SELECT * FROM backgroundJob WHERE dateStarted IS NULL ORDER BY id ASC LIMIT 0,1 FOR UPDATE'); | ||
$foundRows = $command->queryAll(); | ||
if (empty($foundRows)) { | ||
return; | ||
} | ||
|
||
$foundRow = $foundRows[0]; | ||
$this->connection->createCommand('UPDATE backgroundJob SET dateStarted = NOW() WHERE id = :id', ['id' => $foundRow['id']])->execute(); | ||
}); | ||
|
||
return $foundRow; | ||
} | ||
|
||
public function processRow(array $row): void | ||
{ | ||
echo "Processing row: " . $row['id'] . "\n"; | ||
sleep(2); | ||
$this->connection->createCommand('UPDATE backgroundJob SET dateFinished = NOW() WHERE id = :id', ['id' => $row['id']])->execute(); | ||
} | ||
|
||
public function getProcessedEvents(): int { | ||
return $this->processedEvents; | ||
} | ||
|
||
public function getRuntimeInSeconds(): int { | ||
return (new \DateTimeImmutable())->getTimestamp() - $this->startedAt->getTimestamp(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
use yii\db\Migration; | ||
|
||
class m241201_100317_background_jobs extends Migration | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function safeUp(): void | ||
{ | ||
$this->createTable('backgroundJob', [ | ||
'id' => 'BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY', | ||
'siteId' => 'INTEGER DEFAULT NULL', | ||
'consultationId' => 'INTEGER DEFAULT NULL', | ||
'type' => 'VARCHAR(150) NOT NULL', | ||
'dateCreation' => 'TIMESTAMP NOT NULL', | ||
'dateStarted' => 'TIMESTAMP DEFAULT NULL', | ||
'dateUpdated' => 'TIMESTAMP DEFAULT NULL', | ||
'dateFinished' => 'TIMESTAMP DEFAULT NULL', | ||
'payload' => 'MEDIUMBLOB NOT NULL', | ||
]); | ||
|
||
$this->addForeignKey('fk_background_site', 'backgroundJob', 'siteId', 'site', 'id'); | ||
$this->addForeignKey('fk_background_consultation', 'backgroundJob', 'consultationId', 'consultation', 'id'); | ||
$this->createIndex('ix_background_pending', 'backgroundJob', ['dateStarted', 'id'], false); | ||
$this->createIndex('ix_background_todelete', 'backgroundJob', 'dateFinished', false); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function safeDown(): void | ||
{ | ||
$this->dropTable('backgroundJob'); | ||
} | ||
} |