Rack相关知识梳理(二)

简介: 一、Rack中间件 1、什么是中间件 中间件其实就是Ruby应用服务器和Rack应用程序之间执行的代码 2、一个简单的例子 $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'rack' require 'decorator' my_app = l

一、Rack中间件


1、什么是中间件


中间件其实就是Ruby应用服务器和Rack应用程序之间执行的代码


2、一个简单的例子


$LOAD_PATH.unshift(File.dirname(__FILE__)) 
require 'rack'
require 'decorator'
my_app = lambda { |env|
  request = Rack::Request.new(env)
  response = Rack::Response.new 
  response["Content-Type"] = "text/html"
  if request.path_info == "/hello"
    response.write("you say hello")
  else
    response.write("you need say something") 
  end
  response.finish 
}
Rack::Handler::WEBrick.run Decorator.new(my_app), :Port => 3000


这段代码中我们的rack应用程序是一个lambda(lambda具有call方法的) 前面几行没什么好说的,大家看最后一句:


Rack::Handler::WEBrick.run Decorator.new(my_app), :Port => 3000


我们最后传给run的是Decorator对象,这个对象在构造时接受一个rack应用为参数,这个实例既然能被Handler调用,可想而知,我们Decorator必然具备call方法,所以我们也就清楚这个类的结构如下:


class Decorator 
  def initialize(app) 
    ......
  end
  def call(env)
    ......
  end
end


ok,接下来我们编写Decorator


class Decorator 
  def initialize(app)
    @app = app
  end
  def call(env)
    status, headers, body = @app.call(env)
    new_body = "=======beader=========<br/>" 
    body.each { |str| new_body << str }
    new_body << "<br/>======footer=========" 
    headers["Content-Length"] = new_body.bytesize.to_s
    [status, headers, [new_body]]
  end 
end


启动应用,在浏览器上看看效果:


=======beader=========

you say hello

======footer=========


由上可知,Decorator运行在Ruby应用服务器和Rack应用程序之间,因此Decorator就是一个中间件,而且我们可以知道,任何Rack中间件必然是一个合法的Rack应用程序。


3、为什么要用中间件


中间件可以实现通用逻辑和业务逻辑分离,并且这些通用逻辑可以应用到各种各样的业务逻辑中。

 

二、装配中间件


前面我看到一个Rack中间件必然是一个合法的Rack应用程序,那么我们不难想到,一个中间件 外面可以在包装一个中间件,每一个中间件都是独立的,只关心自己的逻辑实现,这样我们就 可以对整个框架或系统中的中间件进行替换,我们还可以用不同的方式去组合多个中间件,从 而满足我们的需求。


1、如何装配中间件


我们往往会在一个应用程序中使用多个中间件,最直接的办法就是new出我们需要的中间件,


例如我们要用middleware1和middleware2两个中间件,那我们可以这样编写代码:


Rack::Handler::WEBrick.run middleware1.new(middleware2.new(rack_app)), :Port => 3000


当然这并不是一个好办法,如果我们要用的中间件非常多,那这段代码就会非常冗⻓,好在Rack已经想到这一点,并且提供了一个非常好的办法:


Rack::Builder


我们利用Builder修改我们之前的代码:


app = lambda { |env|
  request = Rack::Request.new(env) 
  response = Rack::Response.new 
  response["Content-Type"] = "text/html"
  if request.path_info == "/hello"
    response.write("you say hello") 
  else
    response.write("you need say something") 
  end
  response.finish 
}
my_app = Rack::Builder.new { 
  use Decorator
  run app
}.to_app
Rack::Handler::WEBrick.run my_app, :Port => 3000


如果要用多个中间件,那就写成这样:


use middleware1


use middleware2


user middleware3


......


PS:前面大家可能注意到,中间件采用了装饰器的设计模式,所以当使用多个中间件时,各个中间件之间顺序是需要注意的


我们来看看Builder中几个重要的方法


initialize


def initialize(default_app = nil,&block)
  @use, @map, @run, @warmup = [], nil, default_app, nil 
  instance_eval(&block) if block_given?
end


initialize:构造方法,能够接受语句块

 

use


def use(middleware, *args, &block) 
  if @map
    mapping, @map = @map, nil
    @use << proc { |app| generate_map app, mapping } 
  end
  @use << proc { |app| middleware.new(app, *args, &block) } 
end


use:记录要创建的中间件及其顺序。

 

run


def run(app) 
  @run = app
end


run:记录原始的应用程序

 

to_app


def to_app
  app = @map ? generate_map(@run, @map) : @run 
  fail "missing run or map statement" unless app
  app = @use.reverse.inject(app) { |a,e| e[a] } 
  @warmup.call(app) if @warmup
  app
end


to_app:根据use和run中的纪录组合最终的应用程序

相关文章
|
Python
分布式框架ray的基本使用记录
分布式框架ray的基本使用记录
632 0
|
4月前
|
存储 缓存 运维
Lustre架构介绍的阅读笔记-HSM
HSM(Hierarchical Storage Management)是数据分级存储管理,根据数据生命周期、访问特性和设备成本,自动在CPU寄存器、缓存、主存、SSD、HDD、光盘、磁带库等不同存储层级间迁移数据。数据热度分为热、温、冷、冰,对应不同成本、性能和容量。迁移策略可基于人工判断或系统自动计算,并确保业务I/O不受影响、数据一致性。访问频率增加时,数据可反向迁移至更高层级。
|
5月前
|
Kubernetes 关系型数据库 网络架构
ray集群部署vllm的折磨
概括如下: 在构建一个兼容多种LLM推理框架的平台时,开发者选择了Ray分布式框架,以解决资源管理和适配问题。然而,在尝试集成vllm时遇到挑战,因为vllm内部自管理Ray集群,与原有设计冲突。经过一系列尝试,包括调整资源分配、修改vllm源码和利用Ray部署的`placement_group_bundles`特性,最终实现了兼容,但依赖于非官方支持的解决方案。在面对vllm新版本和Ray部署的`reconfigure`方法问题时,又需权衡和调整实现方式。尽管面临困难,开发者认为使用Ray作为统一底层仍具有潜力。
|
并行计算 算法 NoSQL
基于ray 多进程调度管理能力优化networks节点最短路径的并行计算
原生的networkx实现的只能在节点介数度量性任务上达到单核心100的cpu利用率。通过对源码的几行改造我们可以实现多核心的100的利用率。接下来要我们来一起看看是如何实现的多核心100的利用率。
161 0
基于ray 多进程调度管理能力优化networks节点最短路径的并行计算
ES脑裂问题解决方案
ES脑裂问题解决方案
180 0
|
编解码 Shell Linux
使用GFS数据驱动WRF模式场--2层嵌套 全过程学习记录
使用GFS数据驱动WRF模式场--2层嵌套 全过程学习记录
使用GFS数据驱动WRF模式场--2层嵌套 全过程学习记录
|
负载均衡 算法 前端开发
企业集群平台架构设计与实现 haproxy 篇2(二)|学习笔记
快速学习企业集群平台架构设计与实现 haproxy 篇2(二)
企业集群平台架构设计与实现 haproxy 篇2(二)|学习笔记
|
运维 监控 负载均衡
企业集群平台架构设计与实现haproxy篇3(二)|学习笔记
快速学习企业集群平台架构设计与实现haproxy篇3(二)
企业集群平台架构设计与实现haproxy篇3(二)|学习笔记
|
中间件 应用服务中间件 API
Rack相关知识梳理(一)
一、什么是Rack Rack是ruby应用服务器和Rack应用程序之间的接口, 这里面Ruby应用服务器可以是Webrick、thin等,Rack应用程序可以是rails、Sinatra等(其实 现在主流的ruby的Web框架都是基于Rack的)。在上图中,当用户的请求到达应用服务器时,应用服务器会
561 0
|
监控 网络协议 前端开发
企业集群平台架构设计与实现haproxy篇1(二)|学习笔记
快速学习企业集群平台架构设计与实现haproxy篇1(二)