Skip to content

Commit

Permalink
refactor: Move the bump of the file descriptor limit to a dedicated c…
Browse files Browse the repository at this point in the history
…lass (#1189)
  • Loading branch information
theofidry authored Nov 22, 2023
1 parent 31f3bf0 commit e0c5508
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 69 deletions.
6 changes: 3 additions & 3 deletions src/Console/Command/Compile.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use KevinGH\Box\Configuration\Configuration;
use KevinGH\Box\Console\Logger\CompilerLogger;
use KevinGH\Box\Console\MessageRenderer;
use KevinGH\Box\Console\OpenFileDescriptorLimiter;
use KevinGH\Box\Constants;
use KevinGH\Box\MapFile;
use KevinGH\Box\Phar\CompressionAlgorithm;
Expand All @@ -62,7 +63,6 @@
use function implode;
use function is_callable;
use function is_string;
use function KevinGH\Box\bump_open_file_descriptor_limit;
use function KevinGH\Box\check_php_settings;
use function KevinGH\Box\disable_parallel_processing;
use function KevinGH\Box\format_size;
Expand Down Expand Up @@ -221,7 +221,7 @@ public function execute(IO $io): int
// Adding files might result in opening a lot of files. Either because not parallelized or when creating the
// workers for parallelization.
// As a result, we bump the file descriptor to an arbitrary number to ensure this process can run correctly
$restoreLimit = bump_open_file_descriptor_limit(2048, $io);
$restoreLimit = OpenFileDescriptorLimiter::bumpLimit(2048, $io);

try {
$box = $this->createPhar($config, $logger, $io, $debug);
Expand Down Expand Up @@ -721,7 +721,7 @@ private static function configureCompressionAlgorithm(
),
);

$restoreLimit = bump_open_file_descriptor_limit(count($box), $io);
$restoreLimit = OpenFileDescriptorLimiter::bumpLimit(count($box), $io);

try {
$extension = $box->compress($algorithm);
Expand Down
98 changes: 98 additions & 0 deletions src/Console/OpenFileDescriptorLimiter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

/*
* This file is part of the box project.
*
* (c) Kevin Herrera <[email protected]>
* Théo Fidry <[email protected]>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace KevinGH\Box\Console;

use Closure;
use Fidry\Console\IO;
use KevinGH\Box\NotInstantiable;
use Symfony\Component\Console\Output\OutputInterface;
use function function_exists;
use function posix_getrlimit;
use function posix_setrlimit;
use function sprintf;
use const POSIX_RLIMIT_INFINITY;
use const POSIX_RLIMIT_NOFILE;

/**
* @internal
*/
final class OpenFileDescriptorLimiter
{
use NotInstantiable;

private const LIMIT_MARGIN = 128;

/**
* Bumps the maximum number of open file descriptor if necessary.
*
* @return Closure Callable to call to restore the original maximum number of open files descriptors
*/
public static function bumpLimit(int $count, IO $io): Closure
{
$count += self::LIMIT_MARGIN; // Add a little extra for good measure

if (false === function_exists('posix_getrlimit') || false === function_exists('posix_setrlimit')) {
$io->writeln(
'<info>[debug] Could not check the maximum number of open file descriptors: the functions "posix_getrlimit()" and '
.'"posix_setrlimit" could not be found.</info>',
OutputInterface::VERBOSITY_DEBUG,
);

// TODO: loverage noop
return static function (): void {};
}

$softLimit = posix_getrlimit()['soft openfiles'];
$hardLimit = posix_getrlimit()['hard openfiles'];

if ($softLimit >= $count) {
return static function (): void {};
}

$io->writeln(
sprintf(
'<info>[debug] Increased the maximum number of open file descriptors from ("%s", "%s") to ("%s", "%s")'
.'</info>',
$softLimit,
$hardLimit,
$count,
'unlimited',
),
OutputInterface::VERBOSITY_DEBUG,
);

posix_setrlimit(
POSIX_RLIMIT_NOFILE,
$count,
'unlimited' === $hardLimit ? POSIX_RLIMIT_INFINITY : $hardLimit,
);

return static function () use ($io, $softLimit, $hardLimit): void {
// TODO: this check looks redundant
if (function_exists('posix_setrlimit') && isset($softLimit, $hardLimit)) {
posix_setrlimit(
POSIX_RLIMIT_NOFILE,
$softLimit,
'unlimited' === $hardLimit ? POSIX_RLIMIT_INFINITY : $hardLimit,
);

$io->writeln(
'<info>[debug] Restored the maximum number of open file descriptors</info>',
OutputInterface::VERBOSITY_DEBUG,
);
}
};
}
}
66 changes: 0 additions & 66 deletions src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use Phar;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Output\OutputInterface;
use Webmozart\Assert\Assert;
use function bin2hex;
use function class_alias;
Expand All @@ -31,18 +30,13 @@
use function define;
use function defined;
use function floor;
use function function_exists;
use function is_float;
use function is_int;
use function log;
use function number_format;
use function posix_getrlimit;
use function posix_setrlimit;
use function random_bytes;
use function sprintf;
use function str_replace;
use const POSIX_RLIMIT_INFINITY;
use const POSIX_RLIMIT_NOFILE;

/**
* @private
Expand Down Expand Up @@ -241,63 +235,3 @@ static function (int $code, string $message, string $file = '', int $line = -1):
},
);
}

/**
* Bumps the maximum number of open file descriptor if necessary.
*
* @return Closure callable to call to restore the original maximum number of open files descriptors
*/
function bump_open_file_descriptor_limit(int $count, IO $io): Closure
{
$count += 128; // Add a little extra for good measure

if (false === function_exists('posix_getrlimit') || false === function_exists('posix_setrlimit')) {
$io->writeln(
'<info>[debug] Could not check the maximum number of open file descriptors: the functions "posix_getrlimit()" and '
.'"posix_setrlimit" could not be found.</info>',
OutputInterface::VERBOSITY_DEBUG,
);

return static function (): void {};
}

$softLimit = posix_getrlimit()['soft openfiles'];
$hardLimit = posix_getrlimit()['hard openfiles'];

if ($softLimit >= $count) {
return static function (): void {};
}

$io->writeln(
sprintf(
'<info>[debug] Increased the maximum number of open file descriptors from ("%s", "%s") to ("%s", "%s")'
.'</info>',
$softLimit,
$hardLimit,
$count,
'unlimited',
),
OutputInterface::VERBOSITY_DEBUG,
);

posix_setrlimit(
POSIX_RLIMIT_NOFILE,
$count,
'unlimited' === $hardLimit ? POSIX_RLIMIT_INFINITY : $hardLimit,
);

return static function () use ($io, $softLimit, $hardLimit): void {
if (function_exists('posix_setrlimit') && isset($softLimit, $hardLimit)) {
posix_setrlimit(
POSIX_RLIMIT_NOFILE,
$softLimit,
'unlimited' === $hardLimit ? POSIX_RLIMIT_INFINITY : $hardLimit,
);

$io->writeln(
'<info>[debug] Restored the maximum number of open file descriptors</info>',
OutputInterface::VERBOSITY_DEBUG,
);
}
};
}

0 comments on commit e0c5508

Please sign in to comment.