我试图完全理解Rack中并发请求处理的选项.我已经使用async_sinatra来构建一个长轮询应用程序,现在正在尝试使用裸机Rack throw :async和/或Thin的--threaded标志.我对这个问题很满意,但有一些我无法理解的事情.(不,我并不误解并发性的并发性,是的,我确实理解GIL施加的限制).
Q1.我的测试表明thin --threaded(即rack.multithread=true)在不同的线程中同时运行请求(我假设使用EM),这意味着长时间运行的请求A不会阻止请求B(IO旁边).这意味着我的应用程序不需要任何特殊编码(例如回调)来实现并发(同样,忽略阻塞DB调用,IO等).这是我相信我观察到的 - 这是正确的吗?
Q2.还有另一种更常见的实现并发的方法,涉及EventMachine.defer和throw :async.严格来说,不使用线程处理请求.它们是按顺序处理的,但是将它们的繁重工作和回调传递给EventMachine,后者使用async.callback在稍后发送响应.请求A已将其工作卸载到EM.defer后,请求B开始.它是否正确?
Q3.假设上述方法或多或少是正确的,那么一种方法对另一种方法有什么特别的优势吗?显然--threaded看起来像一个魔术子弹.有什么缺点吗?如果没有,为什么每个人都在谈论async_sinatra/ throw :async/ async.callback?也许前者是"我想让我的Rails应用程序在繁重的负载下变得更加快速",而后者更适合具有许多长时间运行请求的应用程序?或者规模是一个因素?只是在这里猜测.
我在MRI Ruby 1.9.2上运行Thin 1.2.11.(仅供参考,我必须使用该--no-epoll标志,因为EventMachine使用epoll和Ruby 1.9.2 存在一个长期的,据称解决但不是真正的问题.这不是重点,但任何见解都是受欢迎的.)
标题非常明显.有没有办法获得标题(除了Rack::Request.env[])?
我有一个看起来像这样的Rack应用程序:
class Foo
def initialize(app)
@app = app
end
def call(env)
env["hello"] = "world"
@app.call(env)
end
end
Run Code Online (Sandbox Code Playgroud)
将我的Rack应用程序挂钩到Rails后,如何env["hello"]从Rails中获取访问权限?
更新:感谢Gaius的回答.Rack和Rails允许您在请求期间或会话持续时间内存储内容:
# in middleware
def call(env)
Rack::Request.new(env)["foo"] = "bar" # sticks around for one request
env["rack.session"] ||= {}
env["rack.session"]["hello"] = "world" # sticks around for duration of session
end
# in Rails
def index
if params["foo"] == "bar"
...
end
if session["hello"] == "world"
...
end
end
Run Code Online (Sandbox Code Playgroud) 我正在编写一个API,它接收一个JSON有效负载作为请求主体.
为了得到它,我正在做这样的事情:
post '/doSomething' do
request.body.rewind
request_payload = JSON.parse request.body.read
#do something with request_payload
body request_payload['someKey']
end
Run Code Online (Sandbox Code Playgroud)
有什么方法可以抽象出来,这样我就不需要为每条路线做这件事了?我的一些路由比这更复杂,因此使用这种方法,request.body将被重新读取并重新分析每个路由,我想避免.
有没有办法让request_payload神奇地可用于路由?像这样:
post '/doSomething' do
#do something with request_payload, it's already parsed and available
body request_payload['someKey']
end
Run Code Online (Sandbox Code Playgroud) 在此之前的Rails 3,您可以修改脚本/服务器文件以SSL参数添加和告诉服务器命令来使用的WEBrick的HTTPS版本.现在,所有这些脚本都消失了,没有人知道如何得到这个使用Rails 3或4个工作?
我有一个中间件,用于使用Bonjour在本地网络应用程序上宣布我的应用程序,但是当从rake或通过控制台调用Rails时,它也会宣布该服务.
我想排除这些情况,并且只在Rails作为服务器运行时使用Bonjour中间件.
中间件配置接受proc以在某些条件下使用以下内容排除中间件proc:
config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env|
env['HTTPS'] != 'on'
}
Run Code Online (Sandbox Code Playgroud)
但是,如何确定是从CLI,控制台还是作为服务器调用Rails?
我有一个与Sinatra一起编写的小型Web服务器.我希望能够将消息记录到日志文件中.我通过http://www.sinatrarb.com/api/index.html和www.sinatrarb.com/intro.html 阅读,我看到Rack有一个名为Rack :: CommonLogger的东西,但我找不到如何访问和用于记录消息的任何示例.我的应用程序很简单所以我把它写成顶级DSL,但我可以切换到从SinatraBase继承它,如果这是所需要的一部分.
假设我有最简单的单文件Sinatra应用程序.他们主页上的你好世界会做.我想在Apache下使用Phusion Passenger,AKA mod_rails运行它.
我正在寻找的功能类似于rake middlewareRails中的命令,但通用机架应用程序除外.
我觉得我在这里遗漏了一些明显的东西,我希望我发布这个时候有人会因为我失踪的谷歌搜索链接而感到羞耻:-)
enable :sessions
get '/logout' do
# What goes here to kill the session?
end
Run Code Online (Sandbox Code Playgroud)