Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
20 / 21
88.89% covered (warning)
88.89%
8 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
WorkerConfiguration
95.24% covered (success)
95.24%
20 / 21
88.89% covered (warning)
88.89%
8 / 9
11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isAsyncLocalEnabled
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 isNotificationLocalEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isAsyncSigningEnabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSigningJobClasses
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getNotificationJobClasses
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDesiredNotificationWorkerCount
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getDesiredWorkerCount
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getWorkerConfig
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Service\Worker;
10
11use OCA\Libresign\AppInfo\Application;
12use OCA\Libresign\BackgroundJob\DeliverNotification;
13use OCA\Libresign\BackgroundJob\SignFileJob;
14use OCA\Libresign\BackgroundJob\SignSingleFileJob;
15use OCA\Libresign\Service\Policy\Provider\Worker\WorkerConfigPolicy;
16use OCP\IAppConfig;
17
18class WorkerConfiguration {
19    private const int MAX_WORKERS = 32;
20    private const int DEFAULT_WORKERS = 4;
21    private const int MAX_NOTIFICATION_WORKERS = 4;
22
23    public const string SIGNING = 'signing';
24    public const string NOTIFICATION = 'notification';
25
26    public function __construct(
27        private IAppConfig $appConfig,
28        private WorkerConfigPolicy $workerConfigPolicy,
29    ) {
30    }
31
32    /**
33     * Queue signing jobs regardless of whether cron or a dedicated process consumes them.
34     */
35    public function isAsyncLocalEnabled(): bool {
36        if (!$this->isAsyncSigningEnabled()) {
37            return false;
38        }
39        return $this->getWorkerConfig()['worker_type'] === 'local';
40    }
41
42    /** Notification worker selection is independent of signing_mode. */
43    public function isNotificationLocalEnabled(): bool {
44        return $this->appConfig->getValueString(Application::APP_ID, 'notification_worker_type', 'local') === 'local';
45    }
46
47    public function isAsyncSigningEnabled(): bool {
48        return $this->appConfig->getValueString(Application::APP_ID, 'signing_mode', 'sync') === 'async';
49    }
50
51    /** @return list<class-string> */
52    public function getSigningJobClasses(): array {
53        return [SignFileJob::class, SignSingleFileJob::class];
54    }
55
56    /** @return list<class-string> */
57    public function getNotificationJobClasses(): array {
58        return [DeliverNotification::class];
59    }
60
61    /** One notification worker by default; cap SMTP-related concurrency. */
62    public function getDesiredNotificationWorkerCount(): int {
63        $workers = (int)$this->appConfig->getValueString(Application::APP_ID, 'notification_parallel_workers', '1');
64        return max(1, min($workers, self::MAX_NOTIFICATION_WORKERS));
65    }
66
67    public function getDesiredWorkerCount(): int {
68        $workerConfig = $this->getWorkerConfig();
69        $numWorkers = (int)($workerConfig['parallel_workers'] ?? self::DEFAULT_WORKERS);
70        return max(1, min($numWorkers, self::MAX_WORKERS));
71    }
72
73    /**
74     * @return array{worker_type: string, parallel_workers: int}
75     */
76    private function getWorkerConfig(): array {
77        $rawValue = $this->appConfig->getValueString(
78            Application::APP_ID,
79            WorkerConfigPolicy::SYSTEM_APP_CONFIG_KEY,
80            '',
81        );
82
83        if ($rawValue === '') {
84            return $this->workerConfigPolicy->defaultValue();
85        }
86
87        return $this->workerConfigPolicy->normalizeValue($rawValue);
88    }
89}