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

Mark24 · February 11, 2022 · Last by myyjjpp replied at February 13, 2022 · 351 hits

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 源码分析 (二) 请求响应

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.