背景 最近在使用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的用法可以看官方...
没有源码模式就是难用,导入外部的md笔记代码都不自动换行,自己造车。。
第二张图中查看代码行数的工具是什么,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返...