瞎扯淡 Roda 源码分析 (二) 请求响应

Mark24 · 2022年02月11日 · 最后由 myyjjpp 回复于 2022年02月13日 · 355 次阅读

Roda 源码分析系列目录

Roda 源码分析

Roda 源码分析 (一) 插件系统

Roda 源码分析 (二) 请求响应

前言

大家好,我是 MARK24。可以叫我 MARK。这是我研究 Roda,做的记录。水平有限,欢迎指正。

研究的 Roda 源码版本 2022 年 2 月 9 日 Roda v3.52.0 dc600b763ebf4f15e11c0428e26b812b9d140911

阅读本文章,你可能获得

  1. Rack 应用概念的了解
  2. Roda 树形路由的原理
  3. Ruby Class 中 extend、include 的技巧
  4. Ruby 中 catch、throw 的使用
  5. 阅读源码的方法

以及欣赏 Roda 的设计等。

我个人水平和精力有限,研究 Ruby 时间不长,自认还是个小学生。如有错误欢迎指正,欢迎交流~

一、预备知识:Rack 工作原理

熟悉的可以跳过 Rack 部分。

Roda 本质上还是有一个 Rack 的应用。用户请求发送至我们的服务器,首先经过 Rack,所以先要明白 Rack 的工作原理。

Rack原理

这篇文章简单的介绍了 Rack 的工作流程

想要深入了解 Rack 可以查看官网源码

有一部国人编写的笔记也可以提供很大的帮助,可以下载:RackProgram.pdf (走我的博客吧,不方便再搞一遍了:Roda 源码分析 (二) 请求响应

二、研究方法总结

Roda 只是一个研究对象,研究方法是通用的。

1.把握宏观,要分清楚几个大类,每个方法在哪个大类下工作,决定了理解他们的角色

大概只需要关注,大类、和 initialize 方法。这里决定了他们初始化的值。

可以理解未来都是围绕着 initialize 里面的数据。

2.从入口开始往上找调用方法看看调用关系

阅读代码不应该从代码层面的 从上往下读。这是错误的。

根据语言的运行特点,以 Ruby 为例。应该以 解释器或者编译的运行顺序来观察源码。

1)代码初始化,进行了什么

class 类声明、以及类中可执行语句在运行。可以关注下 class 中 initialize 中声明的变量,以及动态生成的代码。(Ruby 和其他语言不一样,class 内部也有代码在运行,你应该知道的。)

2) 入口开始,调用关系

建立完内存中初始化的 class 等对象。就可以站在程序运行的角度,从入口调用的顺序 依次查看源码。

3.分析工具

主要使用他们的一些功能帮助阅读。有人可能觉得 DEBUG 工具就够了,我的体会不是这样,DBEUG 的切入点太细碎,而且不够准(我总是这个感觉)。跳转的地方往往涉及面太广,出错了要再次重来。当然可能我不会用啦。不过这些不重要。

真正重要的部分其实是明白 Ruby 工作的机制,以及按照 Ruby 运行的规律,去解读源码的主要部分,识别作者的意图。我觉得这个才比较重要。

1)VScode 编辑器

  • 全局搜索变量、函数定义
  • 查看单个代码文件的 大纲(Outline)即 类、方法 定义一览

2)RubyMine(或者一款 IDE)

  • DEBUG 功能,可以查看过程(不过这不是万能的,因为 DEBUG 对窥探全局并不好用。实际结果还是要以阅读为主)
  • 跳转定义或者使用
  • 修改我们使用的 lib 库 即 Roda 源码,验证自己的猜想(动态语言的优势,一切都是透明的。使用完可以重新安装)

3) 草稿纸

记录重要的引用关系,记录分析和思考。

三、Roda 中使用的 Ruby 的知识

1.class 的上下文中,attr 语句会执行、@语句会执行、def 语句会注册但是不会执行(实例化被实例调用执行),class 上下文的 define_method 会执行

2.def 首次运行只注册不允许,具体的 def 的方法调用顺序,根据 启动 app 的顺序依次调用

3.Ruby 的对象模型,以及 extend、include

这部分主要看插件系统好了。作者在 Ruby 的模型基础上巧妙使用他们构建了自己的插件系统。

比如源码的这部分

master/lib/roda.rb#L494

其实相当核心,我单独介绍了一下 cath 和 throw 的使用

Ruby 的 catch 与 throw

四、Roda 的运行流程

4.1 大致的宏观描述

Roda 主要做四部分工作也对应着他的三个核心类、和一个插件系统

  • class Roda
  • class RodaRequest
  • class RodaResponse
  • Plugins

1.class Roda & Plugins

其中 class Roda 的代码非常少,主要起到一个协调和名字空间的作用。

主要的代码 在 roda/lib/roda.rb#L29 把主要的路基都放在了 module Base 中。

为什么这样做?因为 如果在 Roda 的 class 上下文中定义自己的类方法、实例方法,会成为最高优先级,会覆盖自己的祖先类。

于是 Roda 使用了一个小技巧,把自己的 行为 封装在 Base 模块中,也当成插件 expand 进来

这样插件也可以被 expand,这样就可以实现 插件对 Roda 的方法进行覆盖、或者添加方法,从而实现了插件机制。

2.class RodaRequest

RodaRequest 继承自 Rack::Request 主要添加了 Roda 特色的 路由方法 route.on/is/get/post 等,还有匹配路由的适配器。

3.class RodaResponse

RodaResponse 继承自 Rack::Response

。。。。。。

写到这里,其实这篇文章比较长,然后我本来想贴在这里,可是要把引用主要是我自己博客的引用和图片,全部重弄一遍。。太麻烦了。不高兴弄了。感兴趣可以看下嘛链接,我就不重复劳动了。

我只写了(二),因为第二部分是我自己写的多。 (一)是引用别人多。感兴趣可以完整的。


Roda 源码分析系列目录

Roda 源码分析

Roda 源码分析 (一) 插件系统

Roda 源码分析 (二) 请求响应

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号