这段时间因为疫情在家隔离,闲来无事就想起之前一直想要给 Flask 做一个可以热更新代码的插件系统,于是花了一周左右的时间研读了一遍 Flask 的源代码,并写了一个 Flask 扩展:Flask-Plugin 。
现阶段,使用它你可以:
项目的文档还在编写中,同时我也在示例文件夹( example )中添加了两个简单的小项目,其中一个是移植自 flaskex 项目,而将这个原生 Flask 项目移植为插件仅仅改动了少量代码。
感兴趣的朋友可以前往项目地址: https://github.com/guiqiqi/flask-plugin
欢迎大家试用、反馈 Bug 、提交 PR 、点个 Star 🌟!
1
fgwmlhdkkkw 2022-01-14 10:49:30 +08:00
Python 又不需要编译,热不热有什么区别……
|
2
joApioVVx4M4X6Rf 2022-01-14 10:51:30 +08:00
楼主请问这个插件可以做到给线上的 flask 服务打热补丁吗?就是改了线上服务,过一会就自动加载新代码。
|
3
guiqiqi OP @v2exblog 对的,在不需要重新启动 WebServer 的情况下,插件的代码可以热更新;不过不是自动加载,需要调用插件管理器里的方法进行 unload 以及 load ,具体可以看一下 readme 里面的例子 :)
|
4
joApioVVx4M4X6Rf 2022-01-14 10:55:19 +08:00 1
@guiqiqi 好牛啊,楼主代码结构写得很干净!下午摸鱼抽空读几遍哈哈哈哈
|
5
abersheeran 2022-01-14 11:37:04 +08:00 1
多模块的热更新原子性你是如何保证的?例如:我一次更新了十个文件,其中有一个文件包含语法错误,所以它没办法更新上去,而我项目代码是强耦合的,这个文件没更新上去,整个业务的逻辑都不对。又例如:一个文件已经更新完了,而新请求进来仅此文件被更新,其他文件未更新,则会导致未知的错误。
|
6
guiqiqi OP @abersheeran
首先我觉得插件作为最小的业务逻辑单位,不同插件之间不应该存在强耦合关系,要么他们就应该被设计在一个插件内部而不是分开; 其次如果某一个插件的路由逻辑出现问题,整个插件都不会被成功加载,不会有某一个文件可以被成功加载的问题; 第三,业务逻辑的正确性应该靠测试来保障,而不是插件系统; 第四,依托于 flask 的信号设计,在某一个插件出现加载错误的时候其他的插件可以通过订阅信号源来获得消息,实现解耦合。 |
7
hanswu 2022-01-14 12:39:20 +08:00 1
已 star
|
8
abersheeran 2022-01-14 12:50:37 +08:00 2
@guiqiqi 我说的就是代码分布在多个文件里的同一个插件。假如我的 flask 项目每秒要接收三千个请求,这时候我用你的更新系统去更新了一个包含多文件的插件,如何解决我此次更新全部完成后才作用到新的请求上的需求,而不是更新好了一个模块立刻就被新请求、甚至已有的请求使用了。
|
9
guiqiqi OP @abersheeran
感谢提供思路,项目暂时无法应对这样的情况。 插件系统的路由注册机制与 Blueprint 类似,是依赖 deferred functions 在 app 的 url_map 上操作的,考虑后期在更新插件的过程中设计一个机制,可以 handle 请求,保证更新过程的原子性。 |
10
fish267 2022-01-14 16:24:58 +08:00
楼主,请问这个插件和 debug=True 的区别是啥呀?
|
11
guiqiqi OP @fish267 debug=True 会启动一个监视器,监控文件系统变化,当你的代码发生变化之后,重启 Flask 服务;而插件扩展是在不重启 Flask 的情况下重新加载变化的代码并替换原有路由。
|
12
bbbb 2022-01-14 23:20:00 +08:00 via iPhone 1
star 学习学习
|
14
v2Mark 2022-01-17 10:14:33 +08:00
小方
|