Skip to content

Commit 4d600d0

Browse files
committed
deubgging windows proccess
1 parent 7a10375 commit 4d600d0

File tree

1 file changed

+103
-138
lines changed

1 file changed

+103
-138
lines changed

src/ProcessManager.php

Lines changed: 103 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -7,187 +7,152 @@ class ProcessManager
77
{
88
private string $binaryPath;
99
private $currentProcess = null;
10-
private $isWindows;
10+
private bool $debug;
1111

12-
public function __construct(string $binaryPath)
12+
public function __construct(string $binaryPath, bool $debug = true)
1313
{
1414
$this->binaryPath = $binaryPath;
15-
$this->isWindows = PHP_OS_FAMILY === 'Windows';
16-
17-
// Only register signal handlers on non-Windows systems
18-
if (!$this->isWindows && function_exists('pcntl_async_signals')) {
19-
pcntl_async_signals(true);
20-
pcntl_signal(SIGINT, [$this, 'handleSignal']);
21-
pcntl_signal(SIGTERM, [$this, 'handleSignal']);
22-
}
15+
$this->debug = $debug;
16+
$this->debugLog("ProcessManager initialized with binary: $binaryPath");
2317
}
2418

25-
private function handleSignal(int $signal): void
19+
private function debugLog(string $message): void
2620
{
27-
if ($this->currentProcess && is_resource($this->currentProcess)) {
28-
proc_terminate($this->currentProcess);
29-
proc_close($this->currentProcess);
21+
if ($this->debug) {
22+
echo "[DEBUG] " . date('Y-m-d H:i:s') . " - $message\n";
23+
flush();
3024
}
31-
exit(0);
3225
}
3326

3427
public function execute(array $config, bool $streamOutput): string
3528
{
36-
[$success, $process, $pipes] = $this->openProcess();
37-
$this->currentProcess = $process;
29+
$this->debugLog("Starting execution");
3830

39-
if (!$success || !is_array($pipes)) {
40-
throw new RuntimeException('Failed to start process of volt test');
41-
}
31+
// For Windows, ensure the path is properly quoted
32+
$cmd = PHP_OS_FAMILY === 'Windows'
33+
? '"' . str_replace('/', '\\', $this->binaryPath) . '"'
34+
: $this->binaryPath;
4235

43-
try {
44-
$this->writeInput($pipes[0], json_encode($config, JSON_PRETTY_PRINT));
45-
fclose($pipes[0]);
46-
return $this->handleProcess($pipes, $streamOutput);
47-
} finally {
48-
// Clean up pipes
49-
foreach ($pipes as $pipe) {
50-
if (is_resource($pipe)) {
51-
fclose($pipe);
52-
}
53-
}
36+
$this->debugLog("Command to execute: $cmd");
5437

55-
if (is_resource($process)) {
56-
$exitCode = $this->closeProcess($process);
57-
$this->currentProcess = null;
58-
if ($exitCode !== 0) {
59-
throw new RuntimeException('Process failed with exit code ' . $exitCode);
60-
}
61-
}
62-
}
63-
}
38+
// Create temporary file for input
39+
$tmpfname = tempnam(sys_get_temp_dir(), 'volt_');
40+
$this->debugLog("Created temporary file: $tmpfname");
41+
42+
file_put_contents($tmpfname, json_encode($config, JSON_PRETTY_PRINT));
43+
$this->debugLog("Written config to temporary file");
6444

65-
protected function openProcess(): array
66-
{
6745
$descriptorspec = [
68-
0 => ['pipe', 'r'], // stdin
69-
1 => ['pipe', 'w'], // stdout
70-
2 => ['pipe', 'w'] // stderr
46+
0 => ['pipe', 'r'],
47+
1 => ['pipe', 'w'],
48+
2 => ['pipe', 'w']
7149
];
7250

73-
// Windows-specific process options
74-
$options = $this->isWindows ? [
75-
'bypass_shell' => true,
76-
'create_process_group' => true // Important for Windows process management
77-
] : [
78-
'bypass_shell' => true
79-
];
51+
$this->debugLog("Opening process");
8052

81-
$process = proc_open(
82-
$this->binaryPath,
83-
$descriptorspec,
84-
$pipes,
85-
null,
86-
null,
87-
$options
88-
);
53+
$process = proc_open($cmd, $descriptorspec, $pipes, null, null, [
54+
'bypass_shell' => true,
55+
'create_process_group' => true
56+
]);
8957

9058
if (!is_resource($process)) {
91-
return [false, null, []];
59+
unlink($tmpfname);
60+
throw new RuntimeException('Failed to start process');
9261
}
9362

94-
return [true, $process, $pipes];
95-
}
63+
$this->currentProcess = $process;
64+
$this->debugLog("Process started successfully");
9665

97-
private function handleProcess(array $pipes, bool $streamOutput): string
98-
{
99-
$output = '';
100-
$running = true;
66+
try {
67+
// Write config to stdin
68+
$this->debugLog("Writing config to process");
69+
fwrite($pipes[0], file_get_contents($tmpfname));
70+
fclose($pipes[0]);
71+
unlink($tmpfname);
10172

102-
// Set streams to non-blocking mode
103-
foreach ($pipes as $pipe) {
104-
if (is_resource($pipe)) {
105-
stream_set_blocking($pipe, false);
106-
}
107-
}
73+
$this->debugLog("Starting to read output");
74+
$output = '';
10875

109-
while ($running) {
110-
$read = array_filter($pipes, 'is_resource');
111-
if (empty($read)) {
112-
break;
113-
}
76+
// Set streams to non-blocking
77+
stream_set_blocking($pipes[1], false);
78+
stream_set_blocking($pipes[2], false);
79+
80+
while (true) {
81+
$status = proc_get_status($process);
11482

115-
// Windows-specific: Check process status
116-
if ($this->isWindows) {
117-
$status = proc_get_status($this->currentProcess);
11883
if (!$status['running']) {
119-
$running = false;
84+
$this->debugLog("Process has finished running");
85+
break;
12086
}
121-
}
122-
123-
$write = null;
124-
$except = null;
12587

126-
// Use a shorter timeout on Windows
127-
$timeout = $this->isWindows ? 0.1 : 1;
88+
$read = [$pipes[1], $pipes[2]];
89+
$write = null;
90+
$except = null;
12891

129-
if (stream_select($read, $write, $except, 0, $timeout * 1000000) === false) {
130-
break;
131-
}
132-
133-
foreach ($read as $pipe) {
134-
$type = array_search($pipe, $pipes, true);
135-
$data = fread($pipe, 4096);
92+
if (stream_select($read, $write, $except, 0, 100000)) {
93+
foreach ($read as $pipe) {
94+
$data = fread($pipe, 4096);
95+
if ($data === false || $data === '') {
96+
continue;
97+
}
13698

137-
if ($data === false || $data === '') {
138-
if (feof($pipe)) {
139-
fclose($pipe);
140-
unset($pipes[$type]);
141-
continue;
99+
if ($pipe === $pipes[1]) {
100+
$output .= $data;
101+
if ($streamOutput) {
102+
echo $data;
103+
flush();
104+
}
105+
} else {
106+
fwrite(STDERR, $data);
107+
flush();
108+
}
142109
}
143110
}
111+
}
144112

145-
if ($type === 1) { // stdout
146-
$output .= $data;
147-
if ($streamOutput) {
148-
echo $data;
149-
if ($this->isWindows) {
150-
flush(); // Ensure output is displayed immediately on Windows
151-
}
152-
}
153-
} elseif ($type === 2 && $streamOutput) { // stderr
154-
fwrite(STDERR, $data);
155-
if ($this->isWindows) {
156-
flush();
157-
}
113+
$this->debugLog("Finished reading output");
114+
115+
// Close remaining pipes
116+
foreach ($pipes as $pipe) {
117+
if (is_resource($pipe)) {
118+
fclose($pipe);
158119
}
159120
}
160-
}
161121

162-
return $output;
163-
}
122+
// Get exit code
123+
$exitCode = proc_close($process);
124+
$this->debugLog("Process closed with exit code: $exitCode");
164125

165-
protected function writeInput($pipe, string $input): void
166-
{
167-
if (is_resource($pipe)) {
168-
fwrite($pipe, $input);
169-
if ($this->isWindows) {
170-
fflush($pipe); // Ensure data is written immediately on Windows
126+
if ($exitCode !== 0) {
127+
throw new RuntimeException("Process failed with exit code $exitCode");
171128
}
172-
}
173-
}
174129

175-
protected function closeProcess($process): int
176-
{
177-
if (!is_resource($process)) {
178-
return -1;
179-
}
130+
return $output;
131+
132+
} catch (\Exception $e) {
133+
$this->debugLog("Error occurred: " . $e->getMessage());
134+
135+
// Clean up
136+
foreach ($pipes as $pipe) {
137+
if (is_resource($pipe)) {
138+
fclose($pipe);
139+
}
140+
}
180141

181-
$status = proc_get_status($process);
182-
if ($status['running']) {
183-
// Windows-specific process termination
184-
if ($this->isWindows) {
185-
exec('taskkill /F /T /PID ' . $status['pid']);
186-
} else {
187-
proc_terminate($process);
142+
if (is_resource($process)) {
143+
$status = proc_get_status($process);
144+
if ($status['running']) {
145+
// Force kill on Windows
146+
if (PHP_OS_FAMILY === 'Windows') {
147+
exec('taskkill /F /T /PID ' . $status['pid']);
148+
} else {
149+
proc_terminate($process);
150+
}
151+
}
152+
proc_close($process);
188153
}
189-
}
190154

191-
return proc_close($process);
155+
throw $e;
156+
}
192157
}
193158
}

0 commit comments

Comments
 (0)