Skip to content

Commit

Permalink
JsonResultSetUtils: Query results in bulk..
Browse files Browse the repository at this point in the history
..if there's no limit imposed. PDO runs queries in buffered mode
by default. Fetching without a limit needlessly increases the risk
to require more memory than available.
  • Loading branch information
nilmerg committed Mar 22, 2024
1 parent 0240cc4 commit 572c51c
Showing 1 changed file with 46 additions and 5 deletions.
51 changes: 46 additions & 5 deletions library/Icingadb/Data/JsonResultSetUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,58 @@ public static function stream(Query $query): void
$query->setResultSetClass(__CLASS__);
}

if ($query->hasLimit()) {
// Custom limits should still apply
$query->peekAhead(false);
$offset = $query->getOffset();
} else {
$query->limit(1000);
$query->peekAhead();
$offset = 0;
}

echo '[';
foreach ($query->execute()->disableCache() as $i => $object) {
if ($i > 0) {
echo ",\n";

do {
$query->offset($offset);
$result = $query->execute()->disableCache();
foreach ($result as $i => $object) {
if ($i > 0 || $offset !== 0) {
echo ",\n";
}

echo Json::sanitize($object);

self::giveMeMoreTime();
}

echo Json::sanitize($object);
}
$offset += 1000;
} while ($result->hasMore());

echo ']';

exit;
}

/**
* Grant the caller more time to work with
*
* This resets the execution time before it runs out. The advantage of this, compared with no execution time
* limit at all, is that only the caller can bypass the limit. Any other (faulty) code will still be stopped.
*
* @internal Don't use outside of {@see JsonResultSet::stream()} or {@see CsvResultSet::stream()}
*
* @return void
*/
public static function giveMeMoreTime()
{
$spent = getrusage();
if ($spent !== false) {
$maxExecutionTime = (int) ini_get('max_execution_time');
$timeRemaining = $maxExecutionTime - $spent['ru_utime.tv_sec'] % $maxExecutionTime;
if ($timeRemaining <= 5) {
set_time_limit($maxExecutionTime);
}
}
}
}

0 comments on commit 572c51c

Please sign in to comment.