如果要实现类似 wordpress 那种自动从网络下载、下载后自动安装、安装后可随时“启用 | 禁用”的插件系统。
这个做起来还是挺复杂的,Ruby 这类语言不像 PHP 可以直接 load 文件就可以跑了
一个典型可以参考的是 Redmine,对插件的支持方式是放在指定目录下,需要重启进程才能生效
这样是 OK 的,但是有个关键问题(需要解决),新安装的插件若使网站服务启动失败,就需要一个回滚策略,另外若是引起程序崩溃,可能会是全局性的,这时候就必须登录到服务器的 Shell 来手动维护了
Unicorn 重启的时候,会有个检查机制,如果新 Fork 出来那份进程有错误,将会放弃,老的进程保持不变。
同样这样的机制也在 Puma 里面有,只是据实际使用来看,某些时候(到目前为止仍然未找到原因)会不好使,而导致 Puma 进程 Crash 掉。
然后再说插件的实现,不要把插件看成 Gem!这类自定义插件应该是放在某个目录的,例如 lib/app_plugins
,具体实现就比较复杂的,要看插件的权利有多大。可能需要用到 Rails Engine 的机制。
具体没做过...
engine 的初始化是在宿主 rails app 的初始化时候进行的呀。。。而且 engine 本身初始化甚至可以指定在什么时期去初始化什么代码。。所以不重启是不可以的
或者可以参考 Python 的项目 odoo(OpenERP)的插件设计模式?我记得之前玩的时候,感觉它的插件机制很好,但是 Rails 实现起来貌似真的有难度。
我觉得从 rails 来管理插件,但不负责异常处理,会不会稍微简单点。 做一个加载器,比如 initializer 中的 plugins_manager.rb. 管理插件的开关状态文件(plugins_state.yml),并根据此文件加载 plugins。 插件自负责异常,确保失败时要处理自身在 plugins_state.yml 中的设定,touch restart。