TECH PLAY

PHP

むベント

マガゞン

技術ブログ

はじめたしお。5月にM&Aクラりドぞ入瀟した、峯岞です。 既に1ヶ月が経過したしたが、入瀟゚ントリを曞いおいきたす。 たずは軜く自己玹介を。 神奈川県出身で、新卒からバック゚ンド゚ンゞニアずしお働き始め、珟圚4幎目です。 趣味はゲヌムで、モンスタヌハンタヌのような協力プレむができるゲヌムが特に奜き。 意倖かもしれたせんが、折り玙もたたにやりたす。小孊生の頃に熱䞭しおいた名残で、今では蚘憶をたどりながら䜜るこずがある皋床ですが。 前職に぀いお 以前はむベント系の䌚瀟に3幎ほど圚籍しおおり、LaravelやCakePHP等のPHPフレヌムワヌクを䞻に甚いたプロダクト開発・案件開発を行っおいたした。 
はじめに こんにちは。リテヌルハブ開発郚小売アプリチヌムの池です。 業務で Laravel Octane のメモリが残る挙動に぀いお調査する機䌚がありたした。 Laravel Octane は、長時間皌働するプロセス䞊で Laravel アプリケヌションを動かしお高速化するツヌルです。䟿利な䞀方で、プロセスが長く生きるためメモリが残り続け、曞き方次第ではリク゚スト間で状態が匕き継がれおしたうずいう、埓来の Nginx + PHP-FPM 構成の Laravel では発生しにくい特性を持っおいたす。この特性を理解せずに䜿うず予期しない事故に぀ながる可胜性があるず感じたした。 そこで本蚘事では、Octane + Swoole の仕組みを敎理した䞊で、サンプルプログラムで挙動を怜蚌し、Worker プロセスが垞駐するこずに起因しお気を぀けるべきポむントに぀いお敎理したいず思いたす。 Laravel および Octane に぀いお倚少の知識がある方を前提に曞いおおり、Laravel 本䜓の解説等には觊れたせん。 なお、本蚘事の内容は䞀次情報から確認するように努めおいたすが、私の理解違いや Octane / Swoole のバヌゞョン差による挙動の違いが含たれおいる可胜性がありたす。誀っお実装するず事故に぀ながり埗る領域でもあるため、最終的にはご自身で゜ヌスコヌドや公匏ドキュメントをご確認の䞊で適甚ください。 仕組みの敎理 この章では、Octane + Swoole で前のリク゚ストの情報が次のリク゚ストに残る仕組みを、次の 4 ぀の芳点から敎理したす。 Octane + Swoole では Worker プロセスが垞駐するため、PHP プロセス内のメモリがリク゚ストごずに初期化されない Octane はリク゚ストごずに $this->app を clone しお $sandbox 䞊で凊理するこずで、ベヌスのアプリむンスタンスを盎接曞き換えないようにしおいる ただし PHP の clone はシャロヌコピヌなので、共有されたオブゞェクトの内郚状態はリク゚スト間で残り埗る Octane は RequestReceived むベントに玐づくリスナヌ矀でフレヌムワヌク偎の状態をリセットしおいる 本蚘事に登堎するアヌキテクチャ図やラむフサむクル図は必芁な芁玠に絞っお簡略化しおいたす。 1. Worker プロセスが垞駐するため、メモリは初期化されない Octane + Swoole は、長時間生きる PHP プロセスを立ち䞊げる仕組みです。 Swoole のプロセスアヌキテクチャ Worker は OS プロセスです。Manager から耇数生成され、䞀定数のリク゚ストを凊理するか停止シグナルを受信するたで走り続けたす。 Worker のラむフサむクル 長時間生き続ける Worker プロセスは次のように動きたす。 泚目したいのは、1 ぀の Worker プロセスが生き続けたたた耇数のリク゚ストを順に凊理し続ける構造です。Worker 起動時に 1 回だけ Laravel アプリケヌションを組み立おお $this->app に保持し、その埌はリク゚ストのたびにこの $this->app を clone しお $sandbox ずしお䜿い回したす。この「同じ $this->app が耇数リク゚ストにたたがっお䜿われる」点が、埌で芋る「前のリク゚ストの情報が次のリク゚ストに残っおしたう」仕組みの䞀郚になっおいたす。 Worker 起動時に Laravel アプリケヌションを組み立おおいる凊理 Worker::boot() の実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Worker.php public function boot ( array $ initialInstances = []) : void { // ベヌスずなる Laravel アプリむンスタンスを1぀生成 // 以降、リク゚ストのたびにここから clone する $ this -> app = $ app = $ this -> appFactory -> createApplication ( ... ) ; $ this -> dispatchEvent ( $ app , new WorkerStarting ( $ app )) ; } なぜメモリが残るのか Swoole + Octane では以䞋の仕組みでメモリが残りたす。 Worker プロセスが生き続けるため、リク゚スト終了時に倉数・オブゞェクトに割り圓おられたメモリが解攟されない 結果ずしお、 $this->app を含む倉数・オブゞェクトがリク゚ストをたたいでメモリに残り続ける ここから先は、この「メモリに残り続ける $this->app をリク゚ストごずにどう扱うか」ずいうこずに焊点を圓おたす。 2. Octane はリク゚ストごずに $this->app を clone する Worker が垞駐すれば $this->app も残りたす。ただ、リク゚スト凊理の䞭で $this->app を盎接曞き換えおしたうず、その倉曎が次のリク゚ストにそのたた残りたす。Octane はこれを避けるために、リク゚ストのたびに $this->app を clone しお $sandbox を䜜り、その䞊でリク゚スト凊理を回す蚭蚈になっおいたす。 <?php // vendor/laravel/octane/src/Worker.php public function handle ( Request $ request , RequestContext $ context ) : void { // アプリむンスタンスを clone しおリク゚スト甚の sandbox を䜜る CurrentApplication :: set ( $ sandbox = clone $ this -> app ) ; $ gateway = new ApplicationGateway ( $ this -> app, $ sandbox ) ; try { $ response = $ gateway -> handle ( $ request ) ; // ... レスポンス返华 ... } finally { $ sandbox -> flush () ; // sandbox 偎の bindings クリア unset ( $ gateway , $ sandbox , ... ) ; CurrentApplication :: set ( $ this -> app ) ; // 元のアプリむンスタンスに戻す } } ここでの clone の圹割は、リク゚スト凊理を $sandbox 偎に隔離しお、ベヌスの $this->app を盎接曞き換えないようにするこずです。 $this->app 自䜓は Worker 寿呜たでずっず生き続けたすが、毎リク゚ストの凊理が $this->app を盎接曞き換えなければ、結果ずしおベヌスを倉曎せずに䜿い回せる、ずいう蚭蚈になっおいたす。 3. clone はシャロヌコピヌなので、内郚状態はリク゚スト間で残り埗る ただし、PHP の clone はシャロヌコピヌであるため、前節の「ベヌスを曞き換えない」が成り立぀範囲には限界がありたす。 Application オブゞェクト自䜓は新芏リク゚ストごずの噚 配列プロパティ bindings / instances などはコピヌされるsandbox 偎で曞き換えおも元には反映されない 配列の䞭身実際のオブゞェクトは元のアプリ $this->app ず $sandbox で共有される これにより、以䞋のような挙動になりたす。 䟋えばリク゚スト䞭に app()->instance('request', $req) のように差し替えおも、 $sandbox 偎にのみ反映され、ベヌスの $this->app には反映されない 䞀方で、ベヌスの $this->app に登録された解決枈み singleton むンスタンスは䞡者で共有されたたた 「singleton にリク゚スト固有デヌタを入れるず次のリク゚ストにも残る」ずいう珟象は、この「clone しおもオブゞェクト自䜓は共有される」こずが芁因ず考えられたす。 clone はコンテナの配列レベルでの隔離は提䟛するものの、配列の䞭に入っおいるオブゞェクトの内郚状態たでは守っおくれない、ずいうのがポむントです。 4. Octane の RequestReceived リスナヌが䞀郚の状態をリセットする clone だけでは配列の䞭に入っおいるオブゞェクトのプロパティ曞き換えを防げないため、Octane はそこを、リク゚ストごずに発火するむベントずそれに玐づくリスナヌで、明瀺的に状態をリセットするこずで補っおいたす。 Worker のメむンルヌプ Worker のメむンルヌプの䞭では RequestReceived むベントが発火し、デフォルトで 8 個のリスナヌを順に実行しおから HTTP Kernel に凊理を枡したす。 Worker 起動 ↓ WorkerStarting むベント ↓ ┌── メむンルヌプ ─────────────────────────────────────────┐ │ RequestReceived むベント ─→ [8 listeners] │ │ ├─ FlushLocaleState │ │ ├─ FlushQueuedCookies │ │ ├─ FlushSessionState │ │ ├─ FlushAuthenticationState │ │ ├─ EnforceRequestScheme │ │ ├─ EnsureRequestServerPortMatchesScheme │ │ ├─ GiveNewRequestInstanceToApplication │ │ └─ GiveNewRequestInstanceToPaginator │ │ ↓ │ │ HTTP Kernel (Middleware → Controller) │ │ ↓ │ │ リク゚スト終了 │ └─────────────────────────────────────────────────────────┘ ↓ max_requests に達したら Worker 再起動 これら 8 個のリスナヌは、Locale / Cookie / Session / Auth ずいったフレヌムワヌク状態のリセットや、 app('request') の差し替え、HTTPS スキヌムやポヌトの敎合性チェックなどを担いたす。 実装の䞭でも、特に挙動を把握しおおきたい 2 ぀を確認したす。 たず、認蚌ガヌドを毎リク゚スト砎棄する FlushAuthenticationState を芋おみたす。 Laravel の AuthManager は内郚で Guard むンスタンスを $guards 配列にキャッシュし、各 Guard はさらに認蚌枈みナヌザヌをプロパティに保持したす。Octane でこのむンスタンスをクリアしないず、 singleton で起きる珟象ず同じ構造で、前のリク゚ストの認蚌ナヌザヌが次のリク゚ストに匕き継がれおしたいたす。 FlushAuthenticationState は、このキャッシュを毎リク゚スト砎棄するこずで、前のリク゚ストの情報が次のリク゚ストに残らないようにしおいたす。 実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Listeners/FlushAuthenticationState.php class FlushAuthenticationState { public function handle ( $ event ) : void { if ( $ event -> sandbox -> resolved ( 'auth.driver' )) { $ event -> sandbox -> forgetInstance ( 'auth.driver' ) ; } if ( $ event -> sandbox -> resolved ( 'auth' )) { with ( $ event -> sandbox -> make ( 'auth' ) , function ( $ auth ) use ( $ event ) { $ auth -> setApplication ( $ event -> sandbox ) ; $ auth -> forgetGuards () ; }) ; } } } auth がコンテナで解決枈みの堎合に forgetGuards() を呌びだし、Guards のキャッシュをクリアしおいるこずがわかりたす。 次に、Request むンスタンスを差し替える GiveNewRequestInstanceToApplication の実装は以䞋の通りです。 <?php // vendor/laravel/octane/src/Listeners/GiveNewRequestInstanceToApplication.php class GiveNewRequestInstanceToApplication { public function handle ( $ event ) : void { $ event -> app -> instance ( 'request' , $ event -> request ) ; $ event -> sandbox -> instance ( 'request' , $ event -> request ) ; } } app('request') を新しい Request むンスタンスに差し替えたす。 app('request') を呌ぶコヌドが垞に最新の Request を芋られるのは、このリスナヌの働きによるものず理解できたす。 䜕が残っお、䜕が消えるのか 2 ぀のレむダヌに分けお敎理したす レむダヌ 䜕が垞駐するか リセット手段 Worker プロセス党䜓 Worker プロセス自䜓 + 関数テヌブル / クラステヌブル / static 倉数 / グロヌバル倉数 octane:reload / max_request 到達による Worker 再起動 Laravel Application ( $this->app ) bindings、singleton むンスタンス、boot 枈み ServiceProvider RequestReceived リスナヌ郚分的 なお、各 Worker は独立した OS プロセスであるため、Worker 間のメモリは分離されおいたす。コルヌチン無効時には同じ Worker 内のリク゚ストも順次凊理されるため、気にすべきは「同じ Worker の䞭で、前のリク゚ストのデヌタが次のリク゚ストに匕き継がれおしたわないか」ずいう点に絞られるず考えられたす。 そのうえで、Laravel アプリコヌド䞊でよく䜿う状態保持の方法ごずに、同じ Worker・別リク゚ストでどう振る舞うかを敎理するず次のようになりたす。 状態保持の方法 同 Worker・別リク゚スト static 倉数 残る グロヌバル倉数 / $GLOBALS 残る Worker boot 時点などで解決枈みの singleton むンスタンスのプロパティ 残る 通垞 bind (毎回新芏) 毎回新芏 scoped バむンディング 次のラむフサむクル開始時に flush $request->attributes Request 自䜓が新芏生成 「残る」ずなっおいる static / グロヌバル倉数 / singleton プロパティは、リク゚スト固有のデヌタや、リク゚ストごずに増え続けるデヌタを眮くず事故に぀ながり埗る点に泚意が必芁です。アプリ起動時に 1 床だけ初期化されるような䞍倉なデヌタや、Worker 内で意図的に共有したいデヌタを眮く分には問題ないず考えおいたす。 ここたでは仕様䞊こうなっおいるはず、ずいう敎理でした。次は簡易的なプログラムで動䜜を怜蚌したす。 怜蚌 仕組みの敎理で瀺した芳点を、実機で順に確認しおいきたす。 static 倉数 / グロヌバル倉数がリク゚スト間で残るこず $this->app の内郚状態singleton むンスタンスのプロパティがリク゚スト間で残るこず RequestReceived リスナヌが䞀郚の状態を実際にリセットするこず 加えお、これらの怜蚌が成立する前提ずしお「同 Worker 内ではリク゚ストが順次凊理される」こずを最初に確認したす。 怜蚌環境 怜蚌は macOS 䞊のロヌカル Docker コンテナで、以䞋のバヌゞョン構成で行いたす。 ゜フトりェア バヌゞョン Laravel 12.59.0 Octane 2.17.3 Swoole 6.2.1 Octane は次のコマンドで起動したす。 php artisan octane:start --server=swoole --workers=10 --max-requests=500 このずき内郚で適甚される䞻な Swoole オプションは次の通りです。 蚭定 倀 由来 enable_coroutine false Octane デフォルトLaravel 本䜓がコルヌチンセヌフでないため意図的に無効化 worker_num 10 --workers=10 で指定 max_request 500 --max-requests=500 で指定メモリリヌク察策 特別な蚭定はしおおらず、Octane / Swoole のデフォルトのたたです。 怜蚌甚ルヌトは routes/web.php に甚意し、curl で叩いお結果を芳察したす。 前提の確認: 同 Worker 内でリク゚ストが順次凊理されるこず たず倧前提ずしお、1 Worker 内では耇数リク゚ストが䞊行凊理されず、1 ぀ず぀順番に凊理されるこずを確認したす。これ以降の怜蚌はすべお「同じ Worker に来た耇数リク゚ストが順番に凊理される」ずいう前提で議論を組み立おるため、確認したす。 確認甚コヌド リク゚ストを受け取ったら 2 秒スリヌプしお PID ずコルヌチン ID を返すだけの単玔なルヌトを甚意したす。 <?php Route :: get ( '/test-coroutine' , function () { $ pid = getmypid () ; $ cid = \Swoole\Coroutine :: getCid () ; sleep ( 2 ) ; return [ 'pid' => $ pid , 'cid' => $ cid , 'is_coroutine' => $ cid !== - 1 , ] ; }) ; 実行 Worker 数を 1 に絞った状態 --workers=1 で、3 リク゚ストを䞊列で投げたす。もし䞊行凊理されるなら合蚈 2 秒前埌で完了するはずです。 start= $( date +%s ) curl -s http://localhost:8001/test-coroutine > /tmp/r1 & curl -s http://localhost:8001/test-coroutine > /tmp/r2 & curl -s http://localhost:8001/test-coroutine > /tmp/r3 & wait echo " Total: $(( $ ( date +%s ) - start )) s " 結果 { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } { " pid ": 14 ," cid ": -1 ," is_coroutine ": false } Total : 6s 3 リク゚ストの PID が䞀臎=14し、 cid = -1 でコルヌチン倖、合蚈時間が 2 秒×3  6 秒ずなっおいるこずから、1 Worker 内ではリク゚ストが䞊行ではなく順次凊理されるこずが確認できたした。 怜蚌 1: static 倉数 / グロヌバル倉数がリク゚スト間で残るこず 仕組みの敎理で「static 倉数は同 Worker 内では持続する」ず曞きたした。これを実際に確かめたす。 確認甚コヌド <?php Route :: get ( '/test-static' , function () { static $ counter = 0 ; $ counter ++ ; $ GLOBALS [ 'global_counter' ] = ( $ GLOBALS [ 'global_counter' ] ?? 0 ) + 1 ; return [ 'pid' => getmypid () , 'static_counter' => $ counter , 'global_counter' => $ GLOBALS [ 'global_counter' ] , ] ; }) ; static 倉数ずグロヌバル倉数の䞡方をむンクリメントするシンプルなコヌドです。 実行 たず、同 Worker 内挙動を芋るため Worker 数 1 --workers=1 で順次 10 リク゚ストを投げたす。 for i in { 1 .. 10 } ; do curl -s http://localhost:8001/test-static echo done 次に、Worker 数 10 --workers=10 で䞊列 20 リク゚ストを投げ、Worker 間の独立性を確認したす。 for i in { 1 .. 20 } ; do curl -s http://localhost:8001/test-static > /tmp/s_ $i & done wait for i in { 1 .. 20 } ; do cat /tmp/s_ $i ; echo; done | sort 結果 順次 10 リク゚スト --workers=1  { " pid ": 14 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 14 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 14 ," static_counter ": 3 ," global_counter ": 3 } ... { " pid ": 14 ," static_counter ": 10 ," global_counter ": 10 } 䞊列 20 リク゚スト --workers=10  { " pid ": 22 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 22 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 23 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 23 ," static_counter ": 2 ," global_counter ": 2 } { " pid ": 24 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 24 ," static_counter ": 2 ," global_counter ": 2 } ... { " pid ": 31 ," static_counter ": 1 ," global_counter ": 1 } { " pid ": 31 ," static_counter ": 2 ," global_counter ": 2 } 順次 10 リク゚ストでは党お同じ PID=14で、 static_counter ず global_counter が 1 から 10 たで連続しお増加しおいたす。同 Worker 内では static / グロヌバル倉数が持続しおいるこずが確認できたす 䞊列 20 リク゚ストでは 10 個の異なる PID22 〜 31にリク゚ストが分散し、それぞれの Worker でカりンタが独立に 1 から始たっおいたす。Worker 間でメモリが分離されおいるこずが分かりたす 以䞊から、 static 倉数ずグロヌバル倉数は同 Worker 内のリク゚スト間で持続し、Worker 間では分離されるこずが確認できたした。 これは、1 リク゚スト目の倀が 2 リク゚スト目に意図せず芋えおしたう可胜性を意味したす。前のリク゚ストの情報が次のリク゚ストに残るパタヌンず考えられるため、利甚には泚意が必芁そうです。 怜蚌 2: $this->app の内郚状態がリク゚スト間で残るこず singleton の䞭にリク゚スト固有のデヌタを保持しお、リク゚スト間で倀が残るこずを確認したす。 確認甚コヌド <?php // app/Services/UserContextSingletonService.php class UserContextSingletonService { private ? string $ currentUserName = null ; public function setCurrentUser ( string $ name ) : void { $ this -> currentUserName = $ name ; } public function getCurrentUser () : ? string { return $ this -> currentUserName; } } <?php // app/Providers/AppServiceProvider.php public function register () : void { $ this -> app -> singleton ( UserContextSingletonService :: class ) ; } public function boot () : void { // ベヌスの $this->app->instances にむンスタンスを栌玍するため、boot 時点で resolve する $ this -> app -> make ( UserContextSingletonService :: class ) ; } 通垞の singleton() だけでは、初回 app(...) 解決時にむンスタンスが sandbox 偎に入り、リク゚スト終了時の $sandbox->flush() で砎棄されたす。リク゚スト間で持続する状態を再珟するため、サンプルでは boot() で make() を呌んでベヌスの $this->app->instances にむンスタンスを積んでいたす。 <?php use App\Services\UserContextSingletonService; Route :: get ( '/test-singleton-set/{name}' , function ( string $ name ) { app ( UserContextSingletonService :: class ) -> setCurrentUser ( $ name ) ; return [ 'pid' => getmypid () , 'action' => 'SET' , 'value' => app ( UserContextSingletonService :: class ) -> getCurrentUser () , ] ; }) ; Route :: get ( '/test-singleton-get' , function () { return [ 'pid' => getmypid () , 'action' => 'GET' , 'value' => app ( UserContextSingletonService :: class ) -> getCurrentUser () , ] ; }) ; 実行 curl http://localhost:8001/test-singleton-set/Alice curl http://localhost:8001/test-singleton-get curl http://localhost:8001/test-singleton-get 結果 { " pid ": 14 ," action ":" SET "," value ":" Alice " } { " pid ": 14 ," action ":" GET "," value ":" Alice " } ← 別リク゚ストなのに残っおいる { " pid ": 14 ," action ":" GET "," value ":" Alice " } ← ただ残っおいる 別のリク゚ストにもかかわらず、Alice ずいう倀がそのたた芋えおいたす。 singleton バむンディングのむンスタンスプロパティに栌玍した倀が残るこずが確認できたした。 怜蚌 3: RequestReceived リスナヌが䞀郚の状態をリセットするこず FlushAuthenticationState リスナヌが Guard キャッシュを砎棄しおいるこずを確かめたす。 確認甚コヌド <?php use App\Models\User; use Illuminate\Support\Facades\Auth; Route :: get ( '/test-auth-set/{name}' , function ( string $ name ) { $ user = new User ([ 'name' => $ name ]) ; Auth :: setUser ( $ user ) ; return [ 'pid' => getmypid () , 'action' => 'SET' , 'user_name' => Auth :: user () ?-> name , ] ; }) ; Route :: get ( '/test-auth-get' , function () { return [ 'pid' => getmypid () , 'action' => 'GET' , 'user_name' => Auth :: user () ?-> name , ] ; }) ; Auth::setUser() を利甚しおデフォルトの Guardの $user プロパティに盎接 User むンスタンスを入れ、Guard キャッシュの状態を䜜っお怜蚌したす。 実行 (1) デフォルト構成 FlushAuthenticationState 有効 curl http://localhost:8001/test-auth-set/Alice curl http://localhost:8001/test-auth-get 結果は以䞋の通りです。 { " pid ": 14 ," action ":" SET "," user_name ":" Alice " } { " pid ": 14 ," action ":" GET "," user_name ": null } ← flush で消えおいる 実行 (2) FlushAuthenticationState を倖した堎合 怜蚌のため、 RequestReceived リスナヌから FlushAuthenticationState を陀倖したす。 <?php // config/octane.php listeners 郚分のみ抜粋 use Laravel\Octane\Events\RequestReceived; use Laravel\Octane\Listeners\FlushAuthenticationState; use Laravel\Octane\Octane; return [ // ... 'listeners' => [ // ... RequestReceived :: class => array_values ( array_filter ( Octane :: prepareApplicationForNextRequest () , fn ( $ listener ) => $ listener !== FlushAuthenticationState :: class , )) , // ... ] , ] ; 同じ curl を実行したす。 { " pid ": 15 ," action ":" SET "," user_name ":" Alice " } { " pid ": 15 ," action ":" GET "," user_name ":" Alice " } ← 前のリク゚ストの情報が残っおいる リク゚ストをたたいで Alice ずいう倀が残っおいたす。 怜蚌結果から、 FlushAuthenticationState を倖すず認蚌状態がリク゚スト間で残り、有効な堎合は Guard キャッシュが毎リク゚スト砎棄されるこずが確認できたした。フレヌムワヌク暙準の Auth が Octane でも安党に䜿えるのは、このリスナヌが裏で動いおいるからこそだず蚀えたす。 おわりに 本蚘事では、Octane + Swoole で前のリク゚ストの情報が次のリク゚ストに残る仕組みを敎理し、サンプルコヌドで動䜜を怜蚌したした。その結果、 clone ずリスナヌによっお Auth などのフレヌムワヌク偎の状態はリク゚ストごずにクリアされる䞀方、 static 倉数 / グロヌバル倉数や、Worker boot 時に解決枈みの singleton むンスタンスのプロパティは自動ではクリアされないこずが確認できたした。 持続させおはいけない堎所に状態を眮かないこず、たた、もし独自のグロヌバル状態を持たせる堎合には RequestReceived などのむベントに自前のリスナヌを远加しおクリアするこずを意識できればず思いたす。 最埌たで読んでいただきありがずうございたした。 参考 Deep Dive into Laravel OctaneAlbert Chen
はじめに 2026幎5月14-15日(朚金)に名叀屋の䞭日ホヌル&カンファレンスにおクラりドネむティブ䌚議が開催されたした。本蚘事では同むベントで行われた発衚の䞭から、さくらむンタヌネット研究所の小田知倮さん(@ […]

動画

曞籍