在请求之间共享Sinatra路由内定义的全局变量吗? [英] Is a global variable defined inside a Sinatra route shared between requests?
问题描述
说我有:
get '/' do
$random = Random.rand()
response.body = $random
end
如果我有数千个请求每秒到达/,$ random是否将被共享并在上下文之外泄漏,或者它像get块的 local变量一样起作用?
If I have thousands of requests per second coming to /, will the $random be shared and 'leak' outside the context or will it act like a 'local' variable to the get block?
我想如果它是在 get'/'do
上下文之外定义的,则确实可以共享,但是我想知道是否有我不知道的$红宝石机械师。
I imagine if it was defined outside of the context of get '/' do
it would indeed be shared but I wonder if there's a mechanic to $ in ruby that I'm not aware of.
推荐答案
Sinatra自述文件中有关范围的这一部分对于阅读始终很有帮助,但是如果您只需要为请求保留变量,那么我认为那里我建议您采用以下3种主要方法,而真正的关键是过滤器
This part of the Sinatra README about scope is always helpful to read but if you only need the variable to persist for the request then I think there are 3 main ways I'd suggest going about this, and really the key is a filter
before do
@my_log = []
end
get "/" do
@my_log << "hello"
@my_log << "world"
@my_log.inspect
end
get "/something-else" do
@my_log << "is visible here too"
end
# => output is ["hello", "world"]
@my_log
将在请求结束时超出范围,并在下一个请求开始时重新初始化。它可以通过任何路线访问,因此,例如,如果您使用 pass
将其传递到另一条路线,这将是其他块只能看到的内容由先前的路线封锁。
@my_log
will go out of scope at the end of the request and be re-initialised at the beginning of the next one. It will be accessible by any route, so if for example you used pass
to pass it on to another route that would be the only time the other blocks could see what had been set by the prior route block.
set :mylog, []
然后与上述相同,只需替换 @my_log
使用 settings.my_log
。如果不将之前的$code>块重新初始化,则
@my_log
的内容将在请求中保持不变。
Then same as above, just replace @my_log
with settings.my_log
. Without the before
block reinitialising it then the contents of @my_log
would be persisted across requests.
# I always do this within a config block as then it's only initialised once
config do
uri = URI.parse(ENV["URL_TO_REDIS"])
set :redis, Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
end
现在,可通过 settings.redis
使用redis实例。无需担心可变范围(我将使用本地变量),只需直接推送到Redis。然后,您将两全其美,但是如果您愿意,可以这样做:
Now the redis instance is available via settings.redis
. No need to worry about variable scope (I'd use locals with it), just push straight to Redis. You get the best of both worlds then, but if you want you could do:
before do
@my_log = []
end
get "/" do
@my_log << "hello"
@my_log << "world"
"Hello, World"
end
after do
settings.redis.set "some_key", @my_log
settings.redis.expire "some_key", 600 # or whatever
end
这篇关于在请求之间共享Sinatra路由内定义的全局变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!