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

fix: remove cpu core detection for preview semaphore #38385

Closed
Closed
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
6 changes: 3 additions & 3 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@
* been generated.
*
* This should be greater than 'preview_concurrency_new'.
* If unspecified, defaults to twice the value of 'preview_concurrency_new'.
* Defaults to 8
*/
'preview_concurrency_all' => 8,

Expand All @@ -1170,9 +1170,9 @@
*
* Depending on the max preview size set by 'preview_max_x' and 'preview_max_y',
* the generation process can consume considerable CPU and memory resources.
*
* It's recommended to limit this to be no greater than the number of CPU cores.
* If unspecified, defaults to the number of CPU cores, or 4 if that cannot
* be determined.
* Defaults to 4
*/
'preview_concurrency_new' => 4,

Expand Down
60 changes: 2 additions & 58 deletions lib/private/Preview/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -296,62 +296,6 @@ public static function unguardWithSemaphore($semId): bool {
return sem_release($semId);
}

/**
* Get the number of concurrent threads supported by the host.
*
* @return int number of concurrent threads, or 0 if it cannot be determined
*/
public static function getHardwareConcurrency(): int {
static $width;
if (!isset($width)) {
if (is_file("/proc/cpuinfo")) {
$width = substr_count(file_get_contents("/proc/cpuinfo"), "processor");
} else {
$width = 0;
}
}
return $width;
}

/**
* Get number of concurrent preview generations from system config
*
* Two config entries, `preview_concurrency_new` and `preview_concurrency_all`,
* are available. If not set, the default values are determined with the hardware concurrency
* of the host. In case the hardware concurrency cannot be determined, or the user sets an
* invalid value, fallback values are:
* For new images whose previews do not exist and need to be generated, 4;
* For all preview generation requests, 8.
* Value of `preview_concurrency_all` should be greater than or equal to that of
* `preview_concurrency_new`, otherwise, the latter is returned.
*
* @param string $type either `preview_concurrency_new` or `preview_concurrency_all`
* @return int number of concurrent preview generations, or -1 if $type is invalid
*/
public function getNumConcurrentPreviews(string $type): int {
static $cached = array();
if (array_key_exists($type, $cached)) {
return $cached[$type];
}

$hardwareConcurrency = self::getHardwareConcurrency();
switch ($type) {
case "preview_concurrency_all":
$fallback = $hardwareConcurrency > 0 ? $hardwareConcurrency * 2 : 8;
$concurrency_all = $this->config->getSystemValueInt($type, $fallback);
$concurrency_new = $this->getNumConcurrentPreviews("preview_concurrency_new");
$cached[$type] = max($concurrency_all, $concurrency_new);
break;
case "preview_concurrency_new":
$fallback = $hardwareConcurrency > 0 ? $hardwareConcurrency : 4;
$cached[$type] = $this->config->getSystemValueInt($type, $fallback);
break;
default:
return -1;
}
return $cached[$type];
}

/**
* @param ISimpleFolder $previewFolder
* @param ISimpleFile[] $previewFiles
Expand Down Expand Up @@ -395,7 +339,7 @@ private function generateProviderPreview(ISimpleFolder $previewFolder, File $fil
continue;
}

$previewConcurrency = $this->getNumConcurrentPreviews('preview_concurrency_new');
$previewConcurrency = $this->config->getSystemValueInt('preview_concurrency_new', 4);
$sem = self::guardWithSemaphore(self::SEMAPHORE_ID_NEW, $previewConcurrency);
try {
$preview = $this->helper->getThumbnail($provider, $file, $width, $height);
Expand Down Expand Up @@ -566,7 +510,7 @@ private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPrevie
throw new \InvalidArgumentException('Failed to generate preview, failed to load image');
}

$previewConcurrency = $this->getNumConcurrentPreviews('preview_concurrency_new');
$previewConcurrency = $this->config->getSystemValueInt('preview_concurrency_new', 4);
$sem = self::guardWithSemaphore(self::SEMAPHORE_ID_NEW, $previewConcurrency);
try {
if ($crop) {
Expand Down
2 changes: 1 addition & 1 deletion lib/private/PreviewManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ private function getGenerator(): Generator {
* @since 11.0.0 - \InvalidArgumentException was added in 12.0.0
*/
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
$previewConcurrency = $this->getGenerator()->getNumConcurrentPreviews('preview_concurrency_all');
$previewConcurrency = $this->config->getSystemValueInt('preview_concurrency_all', 8);
$sem = Generator::guardWithSemaphore(Generator::SEMAPHORE_ID_ALL, $previewConcurrency);
try {
$preview = $this->getGenerator()->getPreview($file, $width, $height, $crop, $mode, $mimeType);
Expand Down