Skip to content

Instantly share code, notes, and snippets.

@starfalling
Last active March 7, 2022 05:42
Show Gist options
  • Save starfalling/d46b0071813bb32022e918d0cbdc53f4 to your computer and use it in GitHub Desktop.
Save starfalling/d46b0071813bb32022e918d0cbdc53f4 to your computer and use it in GitHub Desktop.
hyperf hot restart in development
<?php
declare(strict_types=1);
/**
* 使用方式:
* 1. 把文件放置到项目的 bin 目录中,更名为 dev.php
* 2. 开发中启动项目时,使用 dev.php 进行启动,而不是使用 hyperf.php 进行启动
*/
use Swoole\Process as SwooleProcess;
class WatchProcess
{
public $process;
public $pipes;
}
function startHyperf()
{
$process = new SwooleProcess(function (SwooleProcess $worker) {
echo "\n\n👉 ", date('Y-m-d H:i:s'), " about to start hyperf with pid {$worker->pid}\n\n";
include __DIR__ . '/hyperf.php';
}, false);
return $process->start();
}
function getFswatchPath()
{
$fswatch_paths = [
'/usr/local/bin/fswatch',
'/usr/bin/fswatch',
'/bin/fswatch',
'/sbin/fswatch',
];
$fswatch_path = null;
foreach ($fswatch_paths as $fswatch_path) {
if (is_executable($fswatch_path)) {
return $fswatch_path;
}
}
}
function startWatch(): WatchProcess
{
$fswatch_path = getFswatchPath();
if (empty($fswatch_path)) {
echo "\n\n";
echo "‼️ you need to install fswatch first\n";
echo "‼️ for OSX use command: brew install fswatch\n";
echo "\n\n";
exit();
}
$descriptors = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'], // stderr
];
$watch_process = new WatchProcess();
$watch_path = dirname(__DIR__);
$watch_command = "fswatch -Ee '\\.json|\\.lock|.idea|.git|vendor|runtime' --event IsFile '{$watch_path}'";
$watch_process->process = proc_open('exec ' . $watch_command, $descriptors, $watch_process->pipes);
stream_set_blocking($watch_process->pipes[1], false);
return $watch_process;
}
function checkWatch(WatchProcess $watch_process)
{
$stdout = stream_get_contents($watch_process->pipes[1]);
if (empty($stdout)) {
return false;
}
return true;
}
$watch_process = startWatch();
$hyperf_pid = startHyperf();
$is_killing_process = false;
while (true) {
usleep(1000 * 100);
if (checkWatch($watch_process)) {
echo "\n\n👉 ", date('Y-m-d H:i:s'), " about to stop hyperf with pid {$hyperf_pid}\n\n";
SwooleProcess::kill($hyperf_pid);
$is_killing_process = true;
}
$wait_result = SwooleProcess::wait(false);
if ($wait_result === false) {
// 因为前面 kill 一次无法完全杀死进程,这里进行重复 kill
if ($is_killing_process) {
SwooleProcess::kill($hyperf_pid);
}
continue;
}
if ($wait_result['pid'] == $hyperf_pid) {
$is_killing_process = false;
$hyperf_pid = startHyperf();
}
}
@yu1ec
Copy link

yu1ec commented Oct 22, 2019

大佬,这个脚本我在homestead上使用无效哦,我的hyperf框架版本是1.1

@starfalling
Copy link
Author

starfalling commented Nov 15, 2019

大佬,这个脚本我在homestead上使用无效哦,我的hyperf框架版本是1.1

更新了一版,你再试试

@lufujia
Copy link

lufujia commented May 8, 2021

hyperf 2.0 的好像也没有生效哦,是不是要更新一版了

@starfalling
Copy link
Author

2.0 官方有支持了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment