[原創(chuàng)]Swoft源碼剖析-代碼自動(dòng)更新機(jī)制

不同于php-fpm每次請求都會(huì)加載一次PHP代碼,常駐型應(yīng)用只會(huì)讀取一次源文件,為了避免每次發(fā)布/調(diào)試代碼都需要手動(dòng)重啟swoft應(yīng)用,swoft提供了自動(dòng)重載代碼的功能。

文件重載管理進(jìn)程

swoft注冊了一個(gè)名為reload的Process,該進(jìn)程會(huì)在系統(tǒng)引導(dǎo)的最后一個(gè)階段,即swoole啟動(dòng)前啟動(dòng)。該P(yáng)rocess會(huì)啟動(dòng)名為reload的Bean

//Swoft\Process\Bootstrap\Process\ReloadProcess.php
/**
 * Relaod process
 *
 * @Process(name="reload", boot=true)
 */
class ReloadProcess implements ProcessInterface
{
    /**
     * @param \Swoft\Process\Process $process
     */
    public function run(SwoftProcess $process)
    {
        $pname = App::$server->getPname();
        $processName = sprintf('%s reload process', $pname);
        $process->name($processName);

        /* @var \Swoft\Process\Bootstrap\Reload $relaod */
        $relaod = App::getBean(Reload::class);
        $relaod->run();
    }
    //.....
}

文件更新監(jiān)聽Bean

//\Swoft\Process\Bootstrap\Reload::class
/**
*  @Bean()
*/
class Reload
{
    //code .....

    /**
     * 啟動(dòng)監(jiān)聽
     */
    public function run()
    {
        $server = App::$server;
        while (true) {
            sleep($this->interval);
            //FileHelper::md5File()負(fù)責(zé)遞歸的計(jì)算文件夾的md5,其實(shí)改名為FileHelper::md5Dir()更合適,因?yàn)樗唤邮芊悄夸浀奈募鳛閰?shù)
            $md5File = FileHelper::md5File($this->watchDir);//$this->watchDir固定為@app別名對應(yīng)的文件夾
            if (strcmp($this->md5File, $md5File) !== 0) {
                echo "Start reloading...\n";
                $server->isRunning();
                //md5和上次不一致就通知swoole重啟服務(wù)
                $server->getServer()->reload();
                echo "Reloaded\n";
            }
            $this->md5File = $md5File;
        }
    }
}

代碼自動(dòng)重載的機(jī)制也很簡單,每間隔幾秒遞歸的計(jì)算@app目錄下所有php文件的哈希值,發(fā)現(xiàn)文件夾的md5和之前的值有差別則通知swoole重啟work進(jìn)程。

Swoole WorkerStart事件

swoole會(huì)通知各個(gè)worker重啟,觸發(fā)swoole事件WorkerStart,具體的回調(diào)事件如下

namespace Swoft\Bootstrap\Server\ServerTrait.php;
    /**
     * OnWorkerStart event callback
     *
     * @param Server $server server
     * @param int $workerId workerId
     * @throws \InvalidArgumentException
     */
    public function onWorkerStart(Server $server, int $workerId)
    {
        // Init Worker and TaskWorker
        $setting = $server->setting;
        $isWorker = false;

        if ($workerId >= $setting['worker_num']) {
            // TaskWorker
            ApplicationContext::setContext(ApplicationContext::TASK);
            ProcessHelper::setProcessTitle($this->serverSetting['pname'] . ' task process');
        } else {
            // Worker
            $isWorker = true;
            ApplicationContext::setContext(ApplicationContext::WORKER);
            ProcessHelper::setProcessTitle($this->serverSetting['pname'] . ' worker process');
        }
        //觸發(fā)一個(gè)Swoft服務(wù)事件```SwooleEvent::ON_START```,其監(jiān)聽者使用@ServerListener(event=SwooleEvent::ON_START)聲明
        $this->fireServerEvent(SwooleEvent::ON_WORKER_START, [$server, $workerId, $isWorker]);
        //主要是重新掃描加載注解和Bean的重載
        $this->beforeWorkerStart($server, $workerId, $isWorker);
    }

Swoft源碼剖析系列目錄:http://m.itdecent.cn/p/2f679e0b4d58

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前文再續(xù),就書接上一回,隨著與Server、TCP、Protocol的邂逅,Swoole終于迎來了自己的故事,今天...
    蝸牛淋雨閱讀 1,910評論 1 14
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評論 19 139
  • 漆黑的房間 透著僅存的微光 你躲在那時(shí)的遠(yuǎn)方 我尋你在此時(shí)的方向 風(fēng)吹,天也涼 落葉在風(fēng)中飄蕩 我在燭光下思慮 那...
    Afisha閱讀 188評論 0 0

友情鏈接更多精彩內(nèi)容