• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 21191738694

20 Jan 2026 11:53PM UTC coverage: 44.173%. First build
21191738694

Pull #6464

github

web-flow
Merge a66ddc03c into efcf2e03e
Pull Request #6464: feat: stop running worker when update libresign

0 of 52 new or added lines in 1 file covered. (0.0%)

7076 of 16019 relevant lines covered (44.17%)

4.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lib/Service/Worker/WorkerStopper.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2026 LibreCode coop and contributors
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8

9
namespace OCA\Libresign\Service\Worker;
10

11
use OCA\Libresign\BackgroundJob\SignFileJob;
12
use OCA\Libresign\BackgroundJob\SignSingleFileJob;
13
use Psr\Log\LoggerInterface;
14

15
class WorkerStopper {
16
        private const JOB_CLASSES = [
17
                SignFileJob::class,
18
                SignSingleFileJob::class,
19
        ];
20

21
        public function __construct(
22
                private LoggerInterface $logger,
23
        ) {
NEW
24
        }
×
25

26
        public function stopAll(): int {
NEW
27
                $processList = $this->getProcessList();
×
NEW
28
                if ($processList === '') {
×
NEW
29
                        return 0;
×
30
                }
31

NEW
32
                $stopped = 0;
×
NEW
33
                foreach ($this->parseProcessList($processList) as [$pid, $args]) {
×
NEW
34
                        if ($pid === null || $args === null) {
×
NEW
35
                                continue;
×
36
                        }
37

NEW
38
                        if (!$this->matchesWorkerCommand($args)) {
×
NEW
39
                                continue;
×
40
                        }
41

NEW
42
                        if ($this->terminateProcess($pid)) {
×
NEW
43
                                $stopped++;
×
44
                        }
45
                }
46

NEW
47
                return $stopped;
×
48
        }
49

50
        private function getProcessList(): string {
51
                try {
NEW
52
                        $output = shell_exec('ps -eo pid=,args=');
×
NEW
53
                        return $output === null ? '' : trim($output);
×
NEW
54
                } catch (\Throwable $e) {
×
NEW
55
                        $this->logger->debug('Failed to read process list', [
×
NEW
56
                                'error' => $e->getMessage(),
×
NEW
57
                        ]);
×
NEW
58
                        return '';
×
59
                }
60
        }
61

62
        private function parseProcessList(string $processList): array {
NEW
63
                $lines = preg_split('/\R/', $processList) ?: [];
×
NEW
64
                $entries = [];
×
65

NEW
66
                foreach ($lines as $line) {
×
NEW
67
                        $line = trim($line);
×
NEW
68
                        if ($line === '') {
×
NEW
69
                                continue;
×
70
                        }
71

NEW
72
                        $parts = preg_split('/\s+/', $line, 2);
×
NEW
73
                        if (!$parts || count($parts) < 2) {
×
NEW
74
                                continue;
×
75
                        }
76

NEW
77
                        $pid = (int)$parts[0];
×
NEW
78
                        if ($pid <= 0) {
×
NEW
79
                                continue;
×
80
                        }
81

NEW
82
                        $entries[] = [$pid, $parts[1]];
×
83
                }
84

NEW
85
                return $entries;
×
86
        }
87

88
        private function matchesWorkerCommand(string $args): bool {
NEW
89
                $occPath = \OC::$SERVERROOT . '/occ';
×
NEW
90
                if (strpos($args, $occPath) === false) {
×
NEW
91
                        return false;
×
92
                }
NEW
93
                if (strpos($args, 'background-job:worker') === false) {
×
NEW
94
                        return false;
×
95
                }
96

NEW
97
                foreach (self::JOB_CLASSES as $jobClass) {
×
NEW
98
                        if (strpos($args, $jobClass) !== false) {
×
NEW
99
                                return true;
×
100
                        }
101
                }
102

NEW
103
                return false;
×
104
        }
105

106
        private function terminateProcess(int $pid): bool {
NEW
107
                if (function_exists('posix_kill')) {
×
NEW
108
                        return @posix_kill($pid, SIGTERM);
×
109
                }
110

NEW
111
                if (!function_exists('shell_exec')) {
×
NEW
112
                        $this->logger->debug('Cannot stop worker without posix_kill or shell_exec', [
×
NEW
113
                                'pid' => $pid,
×
NEW
114
                        ]);
×
NEW
115
                        return false;
×
116
                }
117

NEW
118
                shell_exec(sprintf('kill -TERM %d 2>/dev/null', $pid));
×
NEW
119
                return true;
×
120
        }
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc