首页/新闻资讯/正文详情

Puma 插件系统详解:从 `tmp_restart` 到自定义插件开发

发布时间:2026/9/27 11:06:51 来源:云帆数科 栏目:资讯中心
Puma 插件系统详解:从 `tmp_restart` 到自定义插件开发
后端网络【免费下载链接】pumaA Ruby/Rack web server built for parallelism项目地址https://gitcode.com/gh_mirrors/pu/puma点击查看免费下载Puma 从 3.0 版本起引入了一套插件Plugin机制允许第三方 gem 和配置文件在服务器配置阶段与服务运行阶段“介入” Puma 的生命周期扩展配置能力与服务运维能力。本文以官方文档 docs/plugins.md 为主线结合仓库内 lib/puma/plugin.rb、lib/puma/plugin/tmp_restart.rb、lib/puma/binder.rb 等源码完整讲解插件的激活方式、内置插件、服务级钩子hook与 Binder 钩子并给出一个可复制的自定义插件编写示例帮助你掌握利用插件为 Puma 做能力扩展的完整链路。插件能做什么为配置与服务运维注入扩展能力插件Plugin本质上是挂在 Puma 生命周期上的扩展单元主要解决两类问题增强配置能力在服务器配置阶段对Puma::DSL做额外配置例如按部署平台预设默认端口、线程数、环境变量等增强服务运维能力在服务器启动后运行后台任务例如监控某个文件、触发重启、上报状态等。官方在docs/plugins.md中给出了两个“样板”插件分别演示了这两类用途tmp_restart当tmp/restart.txt文件被触摸touch时重启服务器属于典型的“启动后后台监控 服务操作”场景heroku打包 Puma 在 Heroku 上使用的默认配置该插件随 Puma 5.0 发布而被逐步淘汰即 sunset属于“配置增强”场景。其中tmp_restart随 Puma 发行版内置因此始终可用而heroku需要额外在 Gemfile 中引入puma-heroku这个 gem或单独安装它后才能使用。插件的激活方式在配置文件里激活插件在 Puma 配置文件中例如config/puma.rb通过plugin name激活# config/puma.rb plugin tmp_restart从源码看Puma::DSL#plugin会直接把插件实例追加到 DSL 内部的plugins数组并调用config.load_plugin(name)完成加载随后在配置文件求值结束后由_offer_plugins统一回调各插件的config钩子见 lib/puma/dsl.rb 与 lib/puma/dsl.rbdef plugin(name) plugins config.load_plugin(name) endConfiguration#load_plugin的实现在 lib/puma/configuration.rb它只是plugins.create name的薄封装——真正的加载逻辑在Puma::PluginLoader中。基于路径的激活机制docs/plugins.md特别强调插件是基于路径需求path requirements激活的。激活heroku插件的效果与执行require puma/plugin/heroku几乎相同。这意味着gem 可以同时提供多个插件每个插件是一个puma/plugin/name.rb文件与 Puma 无关的第三方 gem 也可以为 Puma 提供插件因为加载路径天然兼容 gem 的 lib 目录。这一机制在 lib/puma/plugin.rb 的PluginRegistry#find中有直接体现先在已注册表里查找找不到时就尝试require puma/plugin/#{name}若LoadError则抛出Puma::UnknownPlugindef find(name) name name.to_s if cls plugins[name] return cls end begin require puma/plugin/#{name} rescue LoadError raise UnknownPlugin, Unable to find plugin: #{name} end ... end通过命令行激活除了配置文件Puma 命令行也提供了等价的激活入口。在 lib/puma/cli.rb 中--plugin选项可以多次使用以加载多个插件puma --plugin tmp_restart --plugin systemd对应的测试位于 test/test_cli.rb它验证了命令行加载后Puma::Plugins.find(tmp_restart)与Puma::Plugins.find(systemd)均能命中。仓库内置的另一经典插件systemd的实现在 lib/puma/plugin/systemd.rb相关的test_plugin_systemd.rb与test_plugin_systemd_jruby.rb也印证了该插件的存在。插件 API 全景服务级钩子Server-wide hooksstart与configdocs/plugins.md指出插件可以在服务器server级别使用两个钩子钩子触发时机收到的参数典型用途start服务器启动时launcher发起后台监控、启动辅助线程、增强服务运维功能config服务器配置阶段Puma::DSL对象追加额外配置项、按环境调整默认值从源码验证两个钩子的调用链config钩子配置文件求值完成后Puma::DSL#_offer_plugins会遍历已注册插件凡是respond_to? :config的插件都会收到self即 DSL 实例作为参数见 lib/puma/dsl.rb。这就是插件可以在配置阶段向 DSL 注入新配置的原因。start钩子Puma::Launcher#run在真正启动 runner 之前调用config.plugins.fire_starts self见 lib/puma/launcher.rb。PluginLoader#fire_starts会遍历所有插件实例对实现了start的插件调用i.start(launcher)见 lib/puma/plugin.rb。docs/plugins.md还明确了一条 API 约定Puma::Plugin中的公共方法即被视为插件的公共 APIPublic methods inPuma::Pluginare treated as a public API for plugins。也就是说插件作者只需要关注Puma::Plugin提供的少量方法而不需要理解 Puma 内部庞大对象图。注册与创建Puma::Plugin.createPuma::Plugin.create(blk)是插件注册的核心入口见 lib/puma/plugin.rbdef self.create(blk) name extract_name(caller) cls Class.new(self) cls.class_eval(blk) Plugins.register name, cls end它通过解析调用者caller的栈帧路径用extract_name从puma/plugin/name.rb中提取插件名然后创建一个继承自Puma::Plugin的匿名子类并class_eval传入的块最后注册到全局的Plugins注册表。extract_name使用的CALLER_FILE正则见 lib/puma/plugin.rb专门匹配.../puma/plugin/tmp_restart.rb:3:in ...这类 Ruby 调用栈行格式——这就是“插件文件路径即插件身份”的底层实现。后台任务in_backgroundPuma::Plugin#in_background(blk)让插件把一段代码投递到后台线程池见 lib/puma/plugin.rb。这些后台块会在服务器启动后由Plugins.fire_background以独立线程执行线程名会被设置为plgn bg index便于排查见 lib/puma/plugin.rb。fire_background的调用点位于 lib/puma/single.rb单进程模式与 lib/puma/cluster.rb集群模式说明该机制对两种运行模式都生效。解剖tmp_restart一个完整的官方示例tmp_restart的完整实现只有 36 行见 lib/puma/plugin/tmp_restart.rb是学习插件开发的最佳范本Puma::Plugin.create do def start(launcher) path File.join(tmp, restart.txt) orig nil # 如果无法写入该路径就直接放弃该插件 begin File.write(path, ) unless File.exist?(path) orig File.stat(path).mtime rescue SystemCallError return end in_background do while true sleep 2 begin mtime File.stat(path).mtime rescue SystemCallError # 文件消失视为“不需要重启” else if mtime orig launcher.restart break end end end end end end这个实现同时演示了三个关键点使用start钩子在服务器启动后拿到launcher有了它就可以调用launcher.restart等运维操作使用in_background启动后台循环每 2 秒 stat 一次tmp/restart.txt发现 mtime 比启动时更新就触发重启防御性编码如果tmp/目录不可写比如只读部署环境会捕获SystemCallError直接放弃不拖垮服务器文件被删除时也按“不重启”处理。与之配套的集成测试在 test/test_plugin.rb它通过config: plugin tmp_restart启动服务器再写入tmp/restart.txt断言日志中出现Restarting...完整验证了“触摸文件 → 触发重启”的闭环。Binder 钩子Puma::Binder#before_parsedocs/plugins.md介绍的第二个钩子位于 Binder 层。Puma::Binder负责解析并建立所有监听端点TCP / Unix Socket / SSL它的before_parse方法允许插件在Puma::Binder#parse主逻辑执行之前插入自定义处理逻辑def before_parse(block) before_parse || [] before_parse block if block before_parse end def parse(binds, log_writer nil, log_msg Listening) before_parse.each(:call) ... end上述代码位于 lib/puma/binder.rbbefore_parse用来累积回调块而parse的第一行就会逐个执行这些块然后再开始真正的 URI 解析与 socket 绑定tcp/unix/ssl分支处理见 lib/puma/binder.rb。docs/plugins.md给出了一个实际使用案例puma-acme插件在 v0.1.3 中利用before_parse_hook可重命名为before_parse在解析监听地址前挂接 ACME 证书逻辑从而避免了原本对binder.rb进行 monkey-patching 的必要。这种“在解析绑定之前介入”的能力对于以下插件场景非常有用动态注入或改写监听地址例如按需切换端口、绑定到云平台分配的动态地址在绑定发生前准备 TLS 相关资源证书、密钥按平台或环境条件决定最终绑定方案。动手实践编写一个自定义 Puma 插件结合上面的 API一个最小自定义插件可以这样组织例如放在某个 gem 的lib/puma/plugin/hello.rb从而天然满足基于路径的激活机制# lib/puma/plugin/hello.rb require_relative ../plugin Puma::Plugin.create do # 配置阶段向 DSL 追加自定义配置 def config(dsl) dsl.quiet end # 启动阶段拿 launcher 做运维操作 def start(launcher) launcher.log_writer.log * Hello plugin: server started end end然后只需在配置文件中激活即可# config/puma.rb plugin hello也可以直接以 CLI 方式加载puma --plugin hello编写插件时有几条来自源码的注意事项插件文件的路径必须形如puma/plugin/name.rb因为注册名来自extract_name对调用栈的路径解析且按需加载时PluginRegistry#find会据此执行require puma/plugin/name想让插件在配置阶段生效就实现config(dsl)想让插件在启动后生效就实现start(launcher)respond_to?检查意味着两个钩子都可选需要后台任务时使用in_background它会以独立线程运行并带plgn bg线程名若找不到插件Puma 会抛出Puma::UnknownPlugin定义于 lib/puma/plugin.rb异常消息会区分“无法找到插件”与“文件未正确注册插件”两类情况便于定位问题。小结Puma 的插件系统从 3.0 引入至今始终遵循“路径即身份、钩子即入口”的简洁设计配置文件里一行plugin name即可按需加载start/config两个服务级钩子覆盖了配置注入与运行期运维两种典型诉求Puma::Binder#before_parse则在监听绑定这一更深层的节点上留出了介入点而tmp_restart作为随附的官方样板以不到 40 行的代码完整示范了“监控 后台线程 触发服务操作”的插件范式。无论是复用内置插件还是为部署平台、证书管理、观测上报等场景编写自己的插件上述 API 与调用链都足以支撑起一条完整的扩展路径。赞分享后端网络【免费下载链接】pumaA Ruby/Rack web server built for parallelism项目地址https://gitcode.com/gh_mirrors/pu/puma点击查看免费下载相关推荐突破AI编程限制go-cursor-help如何重塑Cursor编辑器试用体验突破AI编程限制go cursor help如何重塑Cursor编辑器试用体验 在AI编程助手日益普及的今天开发者们面临着一个尴尬的现实最强大的工具往往伴开发工具CLIHelmfile插件系统详解扩展功能与自定义插件开发Helmfile插件系统详解扩展功能与自定义插件开发 Helmfile是一个强大的Kubernetes部署管理工具其核心优势在于灵活的插件系统。通过集成vaAppFlowy 安装从克隆到跑通的完整指南AppFlowy 安装从克隆到跑通的完整指南 这篇教程带你完成 AppFlowy 安装、配置直到在本地跑起来。AppFlowy 是一个免费开源的 AI 协作前端后端企业应用内容协同知识管理AI 应用上一篇阴阳师NPK资源包打不开unnpk解包工具从入门到脚本解密实战指南下一篇三步完成多Excel文件批量查询QueryExcel免费小工具快速上手实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

STM32最小系统硬核解析:供电、复位、时钟与BOOT四大模块设计原理
STM32最小系统硬核解析:供电、复位、时钟与BOOT四大模块设计原理

1. 什么是STM32最小系统?它到底“最小”在哪儿?“STM32单片机最小系统”这个说法,听起来像一句行话,但背后藏着电子工程师入门的第一道硬门槛。我带过几十届学生做课设,也帮上百个初创团队搭过原型板,发现一… · 2026/9/27 11:06:51

解决群晖硬盘兼容警告:把你的硬盘写进白名单
解决群晖硬盘兼容警告:把你的硬盘写进白名单

解决群晖硬盘兼容警告:把你的硬盘写进白名单 【免费下载链接】Synology_HDD_db Add your HDD, SSD and NVMe drives to your Synologys compatible drive database and a lot more 项目地址: https://gitcode.com/GitHub_Trending/sy/Synology_HDD_db 换块硬… · 2026/9/27 11:06:51

GLM-130B 自定义任务评估完全指南:YAML 配置、数据格式与指标扩展
GLM-130B 自定义任务评估完全指南:YAML 配置、数据格式与指标扩展

大模型NLP基础模型模型评测模型量化 【免费下载链接】GLM-130B GLM-130B: An Open Bilingual Pre-Trained Model (ICLR 2023) 项目地址: https://gitcode.com/gh_mirrors/gl/GLM-130B 点击查看 免费下载 GLM-130B 开源仓库提供了一套完整的模型评估框架&#xff0c… · 2026/9/27 11:06:45

VSCode 搭建 STM32 开发环境:TaoToken 统一 Key 接入 Cline 的 settings.json 配置骨架
VSCode 搭建 STM32 开发环境:TaoToken 统一 Key 接入 Cline 的 settings.json 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 12:00:28

STM32调试核心:BOOT0启动模式与NRST复位时序实战解析
STM32调试核心:BOOT0启动模式与NRST复位时序实战解析

1. 项目概述:为什么STM32调试总像在拆炸弹?“STM32开发调试经验总结:那些年踩过的坑”——这标题不是调侃,是无数嵌入式工程师深夜盯着ST-Link指示灯发呆时的真实写照。我带过三届校企联合实训班,亲手陪学生烧过7块最小… · 2026/9/27 12:00:28

STM32硬件调试核心:BOOT0与NRST物理层真相
STM32硬件调试核心:BOOT0与NRST物理层真相

1. 这不是教程,是十年STM32现场排障手记你手里的开发板刚上电,LED不亮,串口没反应,Keil编译通过却烧不进芯片——别急着怀疑代码,先摸摸BOOT0引脚有没有焊锡搭桥;你改了时钟配置,系统跑飞了&… · 2026/9/27 12:00:28

嵌入式硬件调试实战:仿真器、逻辑分析仪与示波器选型指南
嵌入式硬件调试实战:仿真器、逻辑分析仪与示波器选型指南

1. 调试的本质:你首先得知道芯片内部在干什么先说个反直觉的事:很多嵌入式开发者遇到程序“没反应”,第一反应是翻代码、加打印、怀疑编译器优化,折腾半天发现是硬件层面的问题——某个引脚没拉高、时钟配置错了、复位脚一直被拉低… · 2026/9/27 12:00:21

感应电机实时MCSA故障检测含FFT频谱、包络谱、阶次分析、轨道分析、相空间吸引子、模态分析以及时域统计特征Matlab实现
感应电机实时MCSA故障检测含FFT频谱、包络谱、阶次分析、轨道分析、相空间吸引子、模态分析以及时域统计特征Matlab实现

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、算法改进、程序设计科研仿真。🍎 往期回顾关注个人主页:完整代码获取 定制创新 论文复现私信🍊个人信条:做科研&#xff0c… · 2026/9/27 12:00:15

计算机机应用网站建设与维护避坑:5个免费工具省钱指南
计算机机应用网站建设与维护避坑:5个免费工具省钱指南

计算机机应用网站建设与维护避坑:5个免费工具省钱指南 找建站公司报价单上那行小字“基础维护费5000元/年”,是不是让你心里一紧?很多新手转行做网站,第一反应就是找外包,结果花了大几千,最后发现改个Logo还要再掏钱,域名续费更是个无底洞。… · 2026/9/27 11:59:51

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码