Rails 写 Rails 应用的插件系统,有什么最佳实践?

laplace · 2016年06月21日 · 最后由 chenjau 回复于 2016年06月25日 · 2165 次阅读

如果要实现类似 wordpress 那种自动从网络下载、下载后自动安装、安装后可随时 “启用 | 禁用”的插件系统。

  • 应该怎样设计?
  • 有什么最佳实践?

嗯 大概需要重写 rails 的 reload 机制

这个做起来还是挺复杂的,Ruby 这类语言不像 PHP 可以直接 load 文件就可以跑了

一个典型可以参考的是 Redmine,对插件的支持方式是放在指定目录下,需要重启进程才能生效

#2 楼 @jasl 其实 touch tmp/restart.txt 类似的动作,就可以达到重启的目的了

实现完全是可能的

#3 楼 @huacnlee

这样是 OK 的,但是有个关键问题(需要解决),新安装的插件若使网站服务启动失败,就需要一个回滚策略,另外若是引起程序崩溃,可能会是全局性的,这时候就必须登录到服务器的 Shell 来手动维护了

#4 楼 @jasl

Unicorn 重启的时候,会有个检查机制,如果新 Fork 出来那份进程有错误,将会放弃,老的进程保持不变。

同样这样的机制也在 Puma 里面有,只是据实际使用来看,某些时候(到目前为止仍然未找到原因)会不好使,而导致 Puma 进程 Crash 掉。


然后再说插件的实现,不要把插件看成 Gem!这类自定义插件应该是放在某个目录的,例如 lib/app_plugins,具体实现就比较复杂的,要看插件的权利有多大。可能需要用到 Rails Engine 的机制。

具体没做过...

#5 楼 @huacnlee

engine 的初始化是在宿主 rails app 的初始化时候进行的呀。。。而且 engine 本身初始化甚至可以指定在什么时期去初始化什么代码。。所以不重启是不可以的

#6 楼 @jasl 我的意思就是重启,可以重程序里面让自己重启的,其实实现原理很简单

#7 楼 @huacnlee

对,然后还得解决重启失败的后续处理,剩下就是一些人性化考虑(插件状态,管理,安装、卸载)

结论:PHP 是世界上最好的语言。😄

#5 楼 @huacnlee 嗯,我觉得实现上应该不是 gem 这种。大概会是 require、load、include 这种方式,但是插件的(功能、权限)隔离可能需要比较复杂的设计

或者可以参考 Python 的项目 odoo(OpenERP)的插件设计模式?我记得之前玩的时候,感觉它的插件机制很好,但是 Rails 实现起来貌似真的有难度。

我觉得从 rails 来管理插件,但不负责异常处理,会不会稍微简单点。 做一个加载器,比如 initializer 中的 plugins_manager.rb. 管理插件的开关状态文件(plugins_state.yml),并根据此文件加载 plugins。 插件自负责异常,确保失败时要处理自身在 plugins_state.yml 中的设定,touch restart。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册