SSE terminate the script & proc_open leaves child's running in background
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- C
- Star
- 40.4k
- Fork
- 8.2k
- Merge trung bình
- 2 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 96
Mô tả
Description
This code is simply a combination of Mozilla Server-Sent Events Example and PHP proc_open() Example, which make the browser receive the output of a command in real-time.
The first issue is proc_terminate() leaves children running, which is already open since 2006, but people suggested some workarounds (workarounds 1, 2, 4).
The second issue which is why I'm open this, is the PHP script get killed as soon as the SSE connection get closed, which mean kill_process($process) never reached, while in PHP 5.6 the script still alive and terminate normally. I fix it by register_shutdown_function() (workarounds 3).
<?php
// --------------------------------------------
set_time_limit(0);
ini_set('auto_detect_line_endings', 1);
ini_set('max_execution_time', '0');
date_default_timezone_set("America/Halifax");
ob_end_clean();
gc_enable();
header("Content-Type: text/event-stream");
header("Cache-Control: no-store");
header('Access-Control-Allow-Credentials: true');
header("Access-Control-Allow-Origin: *");
header('Access-Control-Expose-Headers: X-Events');
// -------------------------------------------
$process;
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);
$env = '/home';
$pipes;
$process;
// -------------------------------------------
function kill_process() {
global $process;
$status = proc_get_status($process);
if($status['running'] == true) {
// Close all pipes that are still open
fclose($pipes[1]); //stdout
fclose($pipes[2]); //stderr
// Get the parent pid of the process we want to kill
$ppid = $status['pid'];
// Use ps to get all the children of this process, and kill them
$pids = preg_split('/\s+/', `ps -o pid --no-heading --ppid $ppid`);
foreach($pids as $pid) {
if(is_numeric($pid)) {
posix_kill($pid, 9); // SIGKILL
}
}
}
// Workaround 1
posix_kill($ppid, 9);
// Close The Process
proc_close($process);
// Workaround 2
proc_terminate($process);
}
function SendEventToBrowser($event, $msg) {
echo ("event: $msg\n".PHP_EOL);
echo ("data: $msg\n".PHP_EOL);
while (ob_get_level() > 0)
ob_end_flush();
flush();
}
function SendToBrowser($msg) {
echo ("data: $msg\n".PHP_EOL);
while (ob_get_level() > 0)
ob_end_flush();
flush();
}
// ---------------------------------------------
// Workaround 3
register_shutdown_function('kill_process');
// Workaround 4 (exec)
$process = proc_open("exec /bin/bash /home/MyScript.sh", $descriptorspec, $pipes, $env, array());
if(is_resource($process)) {
SendToBrowser('Shell Script Started');
while ($s = fgets($pipes[1])) {
SendToBrowser($s);
// break the loop if the client
// aborted the connection
if (connection_aborted()){
break;
}
}
kill_process($process); // Never Reached
}
SendToBrowser('Shell Script Closed');
?>
PHP Version
PHP 7.4.3 (cli) (built: Mar 2 2022 15:36:52) ( NTS )
Operating System
Ubuntu 20.04.4 LTS
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Chưa xác định được tệp nào trong repository hoặc bài kiểm thử nào. Hãy bắt đầu bằng cách tái hiện việc ngắt kết nối SSE với PHP 7.4.3 trên Ubuntu 20.04, sau đó đọc các entry point proc_open(), proc_terminate() và register_shutdown_function(), cùng với bug về tiến trình con được liên kết. Hoàn thành có nghĩa là tiến trình con không còn chạy sau khi kết nối bị đóng và có kiểm thử hồi quy bao phủ vòng đời đã được báo cáo.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- bash, php
- Lĩnh vực
- backend, operating-systems
- Loại issue
- Lỗi
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Cần làm rõ
- Mức phù hợp với người mới
- 25/100