Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* (feature) Add `task-manager:run-worker` command as wrapper for Symfony messengers `consume` command.
* (improvement) Default to `limit` of 5 messages in run worker command, if no other limit is given.
* (improvement) Validate unique task ids to a specific format.
* (feature) Also purge log entries with a max number entry.


2.0.3
Expand Down
14 changes: 14 additions & 0 deletions src/DependencyInjection/TaskManagerBundleConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,23 @@ public function getConfigTreeBuilder () : TreeBuilder
->scalarPrototype()->end()
->end()
->integerNode("log_ttl")
->setDeprecated("21torr/task-manager", "2.2.0", "Use the `log.ttl` configuration instead.")
->info("The max age of log entries, before they are automatically cleaned.")
->defaultValue(28)
->end()
->arrayNode("log")
->addDefaultsIfNotSet()
->children()
->integerNode("ttl")
->defaultValue(28)
->info("The max age of log entries, before they are automatically cleaned.")
->end()
->integerNode("max_entries")
->defaultValue(1000)
->info("The max number of log entries, before they are automatically cleaned.")
->end()
->end()
->end()
->end();

return $treeBuilder;
Expand Down
13 changes: 12 additions & 1 deletion src/Log/LogCleaner.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
{
public function __construct (
private int $logTtlInDays,
private int $logMaxEntries,
private TaskLogModel $model,
) {}

Expand All @@ -18,7 +19,9 @@ public function cleanLogEntries () : array
{
$deleted = [];

foreach ($this->model->fetchOutdatedTasks($this->logTtlInDays) as $logEntry)
$outdatedTasks = $this->model->fetchOutdatedTasks($this->logTtlInDays, $this->logMaxEntries);

foreach ($outdatedTasks as $logEntry)
{
$deleted[] = \sprintf(
"<fg=yellow>%s</> (%s)",
Expand All @@ -41,4 +44,12 @@ public function getMaxLogEntryAge () : int
{
return $this->logTtlInDays;
}

/**
* Returns the maximum number of log entries to keep
*/
public function getMaxLogEntryNumber () : int
{
return $this->logMaxEntries;
}
}
3 changes: 2 additions & 1 deletion src/Log/Task/CleanOutdatedLogsTaskHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ public function onCleanOutdatedLogs (CleanOutdatedLogsTask $task) : void

$io->title("Task Manager: Cleaning Outdated Log Entries");
$io->comment(\sprintf(
"Cleaning log entries older than <fg=blue>%d days</>",
"Cleaning log entries older than <fg=blue>%d days</> and keeping at most <fg=blue>%d entries</>",
$this->logCleaner->getMaxLogEntryAge(),
$this->logCleaner->getMaxLogEntryNumber(),
));

$deletedEntries = $this->logCleaner->cleanLogEntries();
Expand Down
35 changes: 32 additions & 3 deletions src/Model/TaskLogModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,30 @@ public function createRunForTask (TaskLog $log) : TaskRun
/**
* @return list<TaskLog>
*/
public function fetchOutdatedTasks (int $maxAgeInDays) : array
public function fetchOutdatedTasks (
int $maxAgeInDays,
int $maxEntries,
) : array
{
$oldestTimeQueued = $this->clock->now()
// start with a fixed TTL
$purgeBefore = $this->clock->now()
->sub(new \DateInterval("P{$maxAgeInDays}D"));

// check whether the last entry at "max entries" would be newer than the
// TTL. If so, then adjust the purge date, to fulfill both
$cutOffEntry = $this->getCutoffEntry($maxEntries);

if (null !== $cutOffEntry && $cutOffEntry->getTimeQueued() > $purgeBefore)
{
$purgeBefore = $cutOffEntry->getTimeQueued();
}

/** @var TaskLog[] $entries */
$entries = $this->repository->createQueryBuilder("task")
->select("task, run")
->leftJoin("task.runs", "run")
->where("task.timeQueued <= :oldestTimestamp")
->setParameter("oldestTimestamp", $oldestTimeQueued)
->setParameter("oldestTimestamp", $purgeBefore)
->getQuery()
->getResult();

Expand All @@ -115,6 +128,22 @@ public function fetchOutdatedTasks (int $maxAgeInDays) : array
return $filtered;
}

/**
*
*/
private function getCutoffEntry (int $maxEntries) : ?TaskLog
{
/** @var TaskLog[] $result */
$result = $this->repository->createQueryBuilder("task")
->addOrderBy("task.timeQueued", "DESC")
->setFirstResult($maxEntries)
->setMaxResults(1)
->getQuery()
->getResult();

return $result[0] ?? null;
}

/**
* @return $this
*/
Expand Down
10 changes: 9 additions & 1 deletion src/TaskManagerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ static function (array $config, ContainerBuilder $container) : void
$container->getDefinition(BundleConfig::class)
->setArgument('$sortedQueues', $config["queues"]);

// if the new value was customized, use it. Otherwise keep using
// the old value. If none is set, they use the same default, so everything
// is fine.
$logTtl = 28 !== $config["log"]["ttl"]
? $config["log"]["ttl"]
: $config["log_ttl"];

$container->getDefinition(LogCleaner::class)
->setArgument('$logTtlInDays', $config["log_ttl"]);
->setArgument('$logTtlInDays', $logTtl)
->setArgument('$logMaxEntries', $config["log"]["max_entries"]);
},
);
}
Expand Down