Laravel Octane 和 Swoole 協程的使用分析

之前在工作中使用 Laravel Octane 的 concurrently 處理并發時,發現在隊列和定時任務中不會觸發并發效果。經過分析,作了如下猜測:隊列和定時任務都屬于一個獨立的進程,與 Octane 服務無關,而 Octane concurrently 恰恰需要在 Octane 環境下才能運行。

后來通過代碼進行環境檢測和查看 php 的進程,證明猜想成立。

info('check env', ['served by octane' => isset($_SERVER['LARAVEL_OCTANE']) && ((int)$_SERVER['LARAVEL_OCTANE'] === 1),'on swoole server' => (extension_loaded('swoole') || extension_loaded('openswoole')) && app()->bound(Server::class)
]);

為了能夠在任意代碼中實現并發,我們研究參考了 Hyperf 框架關于協程的代碼,然后抽取了如下兩個類:

<?phpnamespace App\Services;use App\Exceptions\ParallelExecutionException;
use Laravel\Octane\Facades\Octane;
use Throwable;
use Swoole\Coroutine as Co;class Parallel
{protected array $callbacks = [];protected array $results = [];/*** @var Throwable[]*/protected array $throwables = [];public function add(callable $callable, $key = null): void{if (is_null($key)) {$this->callbacks[] = $callable;} else {$this->callbacks[$key] = $callable;}}public function wait(bool $throw = true): array{if (isset($_SERVER['LARAVEL_OCTANE']) && ((int)$_SERVER['LARAVEL_OCTANE'] === 1)) {return Octane::concurrently($this->callbacks, 300000);}app('log')->useLoggingLoopDetection(false);Co\run(function () {foreach ($this->callbacks as $key => $callback) {Co::create(function () use ($callback, $key) {try {$this->results[$key] = $callback();} catch (Throwable $throwable) {$this->throwables[$key] = $throwable;unset($this->results[$key]);}});}});if ($throw && ($throwableCount = count($this->throwables)) > 0) {$message = 'Detecting ' . $throwableCount . ' throwable occurred during parallel execution:' . PHP_EOL . $this->formatThrowAbles($this->throwables);$executionException = new ParallelExecutionException($message);$executionException->setResults($this->results);$executionException->setThrowAbles($this->throwables);unset($this->results, $this->throwables);throw $executionException;}app('log')->useLoggingLoopDetection(true);return $this->results;}private function formatThrowAbles(array $throwables): string{$output = '';foreach ($throwables as $key => $value) {$output .= sprintf('(%s) %s: %s' . PHP_EOL . '%s' . PHP_EOL, $key, get_class($value), $value->getMessage(), $value->getTraceAsString());}return $output;}
}
<?phpnamespace App\Exceptions;use RuntimeException;class ParallelExecutionException extends RuntimeException
{protected array $results = [];protected array $throwables = [];public function getResults(): array{return $this->results;}public function setResults(array $results): void{$this->results = $results;}public function getThrowAbles(): array{return $this->throwables;}public function setThrowAbles(array $throwables): array{return $this->throwables = $throwables;}
}

其中,第一個類的作用是檢測系統是否運行在 Octane 環境下,是則調用Octane concurrently,否則就執行 Swoole 協程代碼,使用起來也比較簡單:

$parallel = new Parallel();
$parallel->add(fn() => $this->analysisStructure(), 'structure');
$parallel->add(fn() => $this->analysisHabit(), 'habit');
['structure' => $structure,'habit' => $habit,
] = $parallel->wait();

之所以沒有完全使用 Swoole 協程,是因為相比之下,Octane 代碼更加優雅,我們在期待著某天更新后,Octane concurrently 也能直接在隊列中運行使用。

第二個類的作用比較簡單,就是對協程中異常的一個定義。

另外在分析過程中,我們也發現了一個比較有意思的事情:
在這里插入圖片描述

如圖所示,當我在路由中運行檢測代碼時,Octane 和 Swoole Server 都為 true;在控制器中運行檢測代碼時,又只有 Octane 為true;為什么會有這樣的區分?我個人猜測是 Octane 在將框架代碼讀進內存時,特意跳過了控制器中的代碼,以避免數據更新不及時等問題。

有知道具體原因的小伙伴,歡迎留言探討。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/713224.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713224.shtml
英文地址,請注明出處:http://en.pswp.cn/news/713224.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#高級:DataGridView的詳解

一、每條數據增加一個按鈕&#xff0c;點擊輸出對應實體 請先確保正確添加實體的名稱和文本&#xff1a; private void button6_Click(object sender, EventArgs e) {//SQL查詢到數據&#xff0c;存于list中List<InforMessage> list bll.QueryInforMessage();//含有字段…

數據頁和緩存頁(BufferPool)

1. 數據頁&#xff08;dataPage&#xff09; 什么是數據頁&#xff1f; 數據頁是 MySQL 存儲引擎在磁盤和內存之間傳輸數據的基本單位&#xff0c;默認大小為16KB。 數據頁的結構&#xff1a; 表頭&#xff1a;儲存與頁相關的元信息&#xff0c;比如&#xff0c;頁號&#…

buuctf_reverse_新年快樂+內涵的軟件

新年快樂 題目&#xff1a;新年快樂.exe 這玩意有殼&#xff01;我去down了upx脫殼 開始放exeinfope的圖片沒截&#xff0c;我記得下載完upx后exeinfoPE顯示還不一樣。留了一張脫殼的實驗圖片&#xff1a; 然后放IDA 我是筆記本鍵盤&#xff0c;shiftFnF12轉字符串 誒呦&…

flutter 安裝流程

flutter文檔 0.安裝flutter https://flutter.cn/docs/get-started/install/windows/desktop?tabdownload 1.jdk 安裝地址 Java Archive | Oracle 2. android studio 下載地址 https://developer.android.com/studio 3.Visual Studio下載地址 下載 Visual Studio Tools …

C++之map

1、map介紹 map是C STL的一個關聯容器&#xff0c;它提供一對一的數據處理能力。其中&#xff0c;各個鍵值對的鍵和值可以是任意數據類型&#xff0c;包括 C 基本數據類型&#xff08;int、double 等&#xff09;、使用結構體或類自定義的類型。 第一個可以稱為關鍵字(key)&…

docker構建hyperf環境

一&#xff0c;構建hyperf 鏡像 官網git https://github.com/hyperf/hyperf-docker 使用dockerfile構建鏡像 根據需要這里我使用8.1 swoole版本的鏡像 在/home/hyperfdocker 目錄中新建一個Dockerfile文件&#xff0c;將這個git上的Dockerfile內容復制粘貼進去 docker build…

HBase總結

基本介紹 特點(高可靠、高性能、面向列、可伸縮) 非關系型數據庫大數據實時處理 表規模達數十億行及數百萬列讀、寫訪問可實時分布式存儲系統 HDFS(Hadoop Distributed File System)文件存儲ZooKeeper作為協同服務列存儲 優點:有利于單列數據查詢缺點:整行讀取時效率較慢,…

毫末智行開年融資,揭幕了自動駕駛最后的賽點

毫末智行日前官宣拿到的超億元B1輪融資&#xff0c;在行業引起了不小的關注。 一方面是信心問題&#xff0c;自動駕駛從早期拼技術到去年拼量產落地&#xff0c;創業公司們的聲量此消彼長&#xff0c;有人領先也有人掉隊&#xff0c;但市場的態度都以謹慎為主&#xff0c;甚至…

Android ANR 日志分析定位

ANR 是 Android 應用程序中的 "Application Not Responding" 的縮寫&#xff0c;中文意思是 "應用程序無響應"。這是當應用程序在 Android 系統上運行時&#xff0c;由于某種原因不能及時響應用戶輸入事件或執行一個操作&#xff0c;導致界面無法更新&…

Kubernetes(k8s第二部分)

資源清單相當于劇本 什么是資源&#xff1a; k8s中所有的內容都抽象為資源&#xff0c;資源實例化后&#xff0c;叫做對象。 1.K8S中的資源 集群資源分類 名稱空間級別&#xff1a; kubeadm k8s kube-system kubectl get pod -n default 工作負載型資源&#xff0c;&a…

指針篇章-(1)

指針&#xff08;1&#xff09;學習流程 —————————————————————————————————————————————————————————————————————————————————————————————————————————————…

Linux:使用nslookup和dig查詢DNS記錄信息

nslookup nslookup&#xff08;Name Server Lookup&#xff09;用于從 DNS 服務器查詢域名、IP 或其他 DNS 記錄信息 示例 查詢域名信息 $ nslookup baidu.comServer: 114.114.114.114 Address: 114.114.114.114#53Non-authoritative answer: Name: baidu.com Add…

springcloud項目,無法在Sentinel Dashboard查看到服務的訪問監控信息【解決方法】

1.問題場景 因為warehouse子項目的前端未開發&#xff0c;所以只能通過postman測試接口訪問&#xff1b; 2.解決方法 package org.sharetek.common.security.config;import cn.dev33.satoken.SaManager; import cn.dev33.satoken.filter.SaServletFilter; import cn.dev33.sat…

【Django】執行查詢—檢索對象(二)

主鍵 (pk) 查詢快捷方式 pk查詢等同于通過模型的 primary key 進行過濾&#xff0c;直接上例子&#xff0c;下面三個語句是等效的。 >>> Blog.objects.get(id__exact14) # Explicit form >>> Blog.objects.get(id14) # __exact is implied >>> …

構筑未來商業智能——數據中臺的戰略視角_光點科技

隨著數字化時代的加速到來&#xff0c;企業對于數據的依賴程度日益增強。數據中臺&#xff0c;作為連接數據與商業決策的關鍵樞紐&#xff0c;已成為企業打造持久競爭優勢的戰略選擇。本文將從戰略的高度&#xff0c;解析數據中臺如何幫助企業捕捉數據紅利&#xff0c;推進業務…

NXP實戰筆記(十一):32K3xx基于RTD-SDK在S32DS上配置LPSPI(同步、異步、DMA、主機、從機、中斷、輪詢)

目錄 1、概述 2、RTD-SDK配置 2.1、配置目標 2.2、主、從機引腳配置 2.3、時鐘配置 2.4、LPSPI配置 2.5、中斷配置 2.6、DMA配置(使用DMA才會配置) 2、dma Logic Instance 2.7、RM配置(使用DMA的情況下必須配置此選項) 3、代碼實現 1、概述 S32K3_低功耗LPSPI輪詢…

第七十六周周報

學習目標&#xff1a; 論文 實驗 學習時間&#xff1a; 2024.2.24-2024.3.1 學習產出&#xff1a; 論文 仔細看了論文"All are Worth Words: A ViT Backbone for Diffusion Models"&#xff0c;”DiffiT: Diffusion Vision Transformers for Image Generation…

備戰藍橋杯Day19 - 堆排序基礎知識

一、每日一題 - 填充 詳細題解 s input() # 輸入字符串 n len(s) # 定義字符的長度 judge ["00", "11", "0?", "1?", "?0", "?1", "??"] # 把所有的情況一一列舉出來 count 0 # 設置計數…

性能優化篇(四) GPU Instancing

使用GPU Instancing可以在一個Draw Call中同時渲染多個相同或類似的物體&#xff0c;從而減少CPU和GPU的開銷。 官方文檔&#xff1a;https://docs.unity3d.com/Manual/GPUInstancing.html 啟用GPU Instancing&#xff0c;我們可以選中一個材質&#xff0c;然后在Inspector窗口…

PostgreSQL教程(二十一):服務器管理(三)之服務器設置和操作

本章討論如何設置和運行數據庫服務器&#xff0c;以及它與操作系統的交互。 一、PostgreSQL用戶賬戶 和對外部世界可訪問的任何服務器守護進程一樣&#xff0c;我們也建議在一個獨立的用戶賬戶下運行PostgreSQL。這個用戶賬戶應該只擁有被該服務器管理的數據&#xff0c;并且…