John Sheehan
John Sheehan

Reputation: 78104

Sinatra global application variable

I've got a simple Sinatra app that I'd like to share a variable across all sessions and requests.

configure do
  @@click_count = 0
end

def send_message(text)
  # ignore, this part works
end

post '/click' do
  @@click_count = @@click_count + 1
  send_message "clicks: #{@@click_count}"
end

The message sent is always clicks: 1 instead of incrementing. I've also tried set :click_count, 0 and then settings.click_count = settings.click_count + 1 but I still get the same thing.

I'm running the server locally with shotgun using shotgun web.rb -p 4567 -E production because another question mentioned in non-production environments the server is restarted on each request which loses the state.

Any ideas how to get this to work?

Upvotes: 4

Views: 3986

Answers (2)

matt
matt

Reputation: 79733

Sinatra itself doesn’t restart on each request in development mode (it used to), but shotgun has that effect:

Each time a request is received, it forks, loads the application in the child process, processes the request, and exits the child process.

Simply use ruby web.rb, and everything should work (modulo threading issues that from you comment it looks like you’re aware of).

Upvotes: 5

David Grayson
David Grayson

Reputation: 87396

I am not sure how often the configure block gets run. Try using a global variable (e.g. $click_count) instead of a class instance variable and initialize it at the very top of your program, outside of any block.

Upvotes: 2

Related Questions