背景 最近在使用calibre-web管理電子書,不過很多時候還是需要用到Calibre桌面版軟件,批量管理,編輯電子書等功能,因此需要使用calibre-douban元數據...

背景 最近在使用calibre-web管理電子書,不過很多時候還是需要用到Calibre桌面版軟件,批量管理,編輯電子書等功能,因此需要使用calibre-douban元數據...
多路復用I/O 部分第2個異步的代碼沒有實現完整,主要是 Stream.write() 生成器的問題。
Server._handle() 和 Stream.read() 都是監聽 select.POLLIN 事件,通過棧組合到一起。
先處理棧頂的 Stream.read(),讀取完成后的數據 send 回 Server._handle(),繼而傳遞給
Stream.write(). 而 Stream.write() 需要監聽 select.POLLOUT,這部分更新監聽事件有問題:
- IOLoop.add_handler() 為同一 fd 多次注冊會報錯,引入的 IOLoop.modify() 可能是為了解決這個問題,但并沒有被調用
- 修改注冊事件寫在了 Stream.write() 內部,這樣會出現反復修改注冊事件。沒有重用原來 stack handler 策略
另外,這里棧結構實現利用 list 就足夠了,沒必要 collections.deque。
最后,非常感謝作者的分享,很有啟發。
簡明網絡I/O與并發 --- I/O簡明網絡I/O與并發 --- I/O簡明網絡I/O與并發 --- 并發 計算機的基本組成其實很簡單,處理器,存儲器加上輸入輸出設備,就能構成計算機。大至超級計算機,小到手機等...
簡明網絡I/O與并發 --- I/O簡明網絡I/O與并發 --- 并發 計算機的基本組成其實很簡單,處理器,存儲器加上輸入輸出設備,就能構成計算機。大至超級計算機,小到手機等...
Worker.notify() 用于 Worker.tmp ctime 訪問時間,而 Worker.tmp ctime 被用在 Arbiter.run() 循環下 `Arbiter.murder_workers()` 中,murder_workers() 負責清理 idle workers。(超時受 timeout 參數控制)
當接收到 TERM 信號時,信號從 Arbiter 下發到 Worker,TERM 信號下 Worker 并不直接殺死自己(QUIT,INT除外),而是 `Worker.alive = False` 控制請求循環停止接受新請求。
上面我介紹的這種情況對應 `Arbiter.handle_term()` 信號處理,實際調用 `Arbiter.stop()`,第一次 Arbiter 下發 TERM 信號讓 worker 停止接受新請求,graceful_timeout 后直接 SIGKILL 殺死 worker。(據我所搜索到的,SIGKILL 并不能捕捉掛載自定義處理函數)
還有一點,timeout 和 graceful_timeout 不是一碼事。timeout 用于控制請求超時,graceful_timeout 則是殺死 worker 前的等待時間(等待正在處理的請求處理完)。前者相關代碼在 SyncWorker.run(), Arbiter.murder_workers() 中,后者相關代碼在 Arbiter.stop() 中。
Gunicorn源碼分析(二)Worker進程Gunicorn.worker實現了不同類型的work進程,有單進程、多線程、多協程等形式。 gunicorn.worker目錄結構: 主要看以下幾個源碼文件 base.py...
最近使用Gunicorn+Flask部署了一套服務,順便研究下Gunicorn的源碼,看看Python 的Prefork模型是如何實現的。具體Gunicorn的用法可以看官方...
第二張圖中查看代碼行數的工具是什么,Pycharm 中插件?
FastAPI 源碼閱讀 (一) ASGI應用本章開啟FastAPI的源碼閱讀,FastAPI是當下python web中一顆新星,是一個劃時代的框架。從誕生便是以快速和簡潔為核心理念。它繼承于Starlette,是在其...
本章開啟FastAPI的源碼閱讀,FastAPI是當下python web中一顆新星,是一個劃時代的框架。從誕生便是以快速和簡潔為核心理念。它繼承于Starlette,是在其...
Gunicorn.worker實現了不同類型的work進程,有單進程、多線程、多協程等形式。 gunicorn.worker目錄結構: 主要看以下幾個源碼文件 base.py...
有在B站直播(看動漫/電影吐槽,玩游戲,敲代碼)的想法很久了,但是一直沒有付諸實踐。我有舞臺恐懼癥,在直播場景下說話也會說不利索。不過兵馬未動,糧草先行,我們今天記錄一下怎么...
@Gascognya 那也蠻厲害了。我是用了一段時間 Web 框架,文檔翻過一遍才開始讀源碼。不知道是你運氣好還是有人指點,starlette 已經是非常優雅的框架了,簡直藝術品。
Starlette 源碼閱讀 (階段總結一)在前五篇中,筆者對applications.py,routing.py,requests.py,responses.py進行了解讀。了解到了從app進入,到endpoint返...
這里提一下 _TemplateResponse 中不直接發送渲染好的HTML內容,而先發送一個 "type": "http.response.template" 響應的原因。scope["extensions"] 是不是 ASGI 規范指定的字段不是很確定,但這里的 "http.response.template" 類型響應從邏輯上不是必要的(只要直接給客戶端返回HTML內容就可以了,沒必要把 template, context 先返回)。在代碼中全文搜索,猜測這可能是配合 testclient.py 做出的響應。
Starlette 源碼閱讀 (十四) 配置文件與模板config.py 配置文件的方式很多,starlette提供了一種.env文件的配置方式,實際像py,json,xml都是非常合適的配置文件。 Environ環境變量對象 ...
這里值得一提的是 BackgroundTask 中 run_in_threadpool().
BackgroundTask 是把一個函數封裝,通過非阻塞方式去調用它。
如果函數時一個協程函數,通過 await 執行,當前事件循環 loop 會控制其切換。
如果函數不是一個協程,則調用 await run_in_threadpool() 執行此函數。乍一看名字好像是放到一個線程池里執行,實際是通過 loop.run_in_executor() 把函數交給當前事件循環的 executor 執行,其實還是在當前 loop 中控制切換。
至于 loop 中 Executor 是什么,我也不是很理解。
Starlette 源碼閱讀 (十) 異步與后臺任務background.py & concurrency.py 實際上筆者對于異步的深層原理了解并不透徹,還只停留在勉強會用的水平。日后會對這方面只是進行系統性自下而上的學習。...
我覺得作者可能有點把順序搞反了。應該先去理解 ASGI 規范再來看 ASGI 的實現(也就是這里的 Starlette)。
Starlette 源碼閱讀 (階段總結一)在前五篇中,筆者對applications.py,routing.py,requests.py,responses.py進行了解讀。了解到了從app進入,到endpoint返...
ASGI 是一套通信標準,方便遵循 ASGI 標準的服務器和應用之間通信。Starlette 算是實現了 ASGI 的應用或者工具集、框架。ASGI 應用這邊要給出一個可調用對象,對應 Starlette 中 app 對象 :Starlette 實例,其調用方式為 func(self, scope: Scope, receive: Receive, send: Send). 由實現了 ASGI 的 Web 服務器發起調用,故而調用參數 scope, receive, send 都是 Web 服務器提供。
目前常用的 ASGI 服務器有 Uvicorn, Hypercorn, Daphne.
在部署時還會用到 Nginx, Apache 等服務器。Uvicorn 和 Nginx 都屬于 Web 服務器,但 Uvicorn 是專一型的:實現了 ASGI 規范,只講 HTTP, WebSockets。而 Nginx 屬于通用性服務器(并發能力強、反代靈活等)。Uvicorn 與 Nginx 通過 HTTP 協議通信。
對于不同請求的分發,Starlette 可以通過處理不同路徑的請求,Host 處理不同域名的請求,傳遞給不同的 Route 或者說 request handler。Nginx 也可以針對路徑、域名分發請求,只不過是轉發給不同的 app。
Starlette 源碼閱讀 (階段總結一)在前五篇中,筆者對applications.py,routing.py,requests.py,responses.py進行了解讀。了解到了從app進入,到endpoint返...