1

我在 Sinatra 应用程序中有一个全局变量,我想使用 Rakefile 中的计划任务对其进行更新。请注意,该应用程序托管在 Heroku 上。我已经设置了助手来访问这个变量。

get '/' do
    @@var
end

helpers do
    def get_var
        return @@var
    end

    def set_var(value)
        @@var = value
    end
end

这是我的 Rakefile 中的任务:

task :do_something do
    Sinatra::Application.set_var(get_data)
end

def get_data
    # Retrieve value from external source
    ...
    return val
end

我遇到的问题是任务执行正确,但 Sinatra 应用程序中的变量从未更新。我认为这是因为Sinatra::Application从 Rakefile 中调用实际上会从我尝试更新的主实例中创建一个单独的应用程序实例。

我想知道它们是否是一种从 Rakefile 任务中访问正在运行的 Sinatra Web 应用程序范围的方法。

*注意:我可以将在计划任务中检索到的值写入数据库,然后从 Sinatra 应用程序访问它,但这将是多余的,因为此变量更新频率很低,但检索频率很高,我宁愿将其保留在内存以便于访问。为了避免转向数据库,我研究了 Memcache 和 Redis,但我再次觉得这对于单个值来说太过分了。随意不同意这一点。

编辑:关于 Alexey Sukhoviy 的评论,Heroku 不允许写入 tmp 目录之外的文件,并且这些文件的存活时间不足以满足应用程序的需求。

4

1 回答 1

2

我最终使用 Memcache 存储变量。这与 Heroku 配合得很好,因为他们为它提供了一个免费的附加组件。Dalli gem为 Memcache 提供了一个简单的 Ruby 接口。在我的 Sinatra 应用程序文件中,我设置了以下选项:

require 'dalli'

set :cache, Dalli::Client.new

然后我可以从 Rakefile 中恢复存储的变量:

task :do_something do
    Sinatra::Application.settings.cache.set('var', get_data)
end

然后我可以在我的 Sinatra 控制器中再次访问这个变量:

settings.cache.get('var')
于 2012-11-12T23:27:07.837 回答