Search code examples
rubyherokusinatrarake-task

Accessing Sinatra application scope from Rake task


I have a global variable in a Sinatra application that I want to update with a scheduled task from my Rakefile. Note that the application is hosted on Heroku. I have set up helpers in order to access this variable.

get '/' do
    @@var
end

helpers do
    def get_var
        return @@var
    end

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

Here is the task in my Rakefile:

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

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

The problem I run into is that the task executes properly, but the variable in the Sinatra application is never updated. I assume this is because calling Sinatra::Application from within the Rakefile actually creates a separate instance of the application from the primary instance that I am trying to update.

I want to know if their is a way to access the scope of the running Sinatra web app from within a Rakefile task.

*Note: I could just write the value retrieved in the scheduled task to a database and then access it from the Sinatra app, but that would be overkill because this variable is updated so infrequently but retrieved so regularly that I would prefer to keep it in memory for easier access. I have looked into Memcache and Redis in order to avoid turning to a database, but again I feel that this would be excessive for a single value. Feel free to disagree with this.

EDIT: In regards to Alexey Sukhoviy's comment, Heroku does not allow writing to files outside of the tmp directories, and these are not kept alive long enough to satisfy the needs of the application.


Solution

  • I ended up storing the variable using Memcache. This plays well with Heroku since they provide a free add-on for it. The Dalli gem provides a simple interface with Ruby for Memcache. In my Sinatra app file, I set the following options:

    require 'dalli'
    
    set :cache, Dalli::Client.new
    

    I then am able to recover the stored variable from the Rakefile:

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

    I can then access this variable again in my Sinatra controller:

    settings.cache.get('var')