Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing Ruby variables between Sinatra requests

I am trying to write a simple quiz game in sinatra and I need to have common objects accessible for all users (lobby state, chat messages etc.). The problem is that Sinatra reloads the code after every request and objects become in initial state. How to implement it?

like image 787
Veselin Genadiev Avatar asked Feb 21 '14 21:02

Veselin Genadiev


1 Answers

Well, the topic is a bit tricky. Sinatra actually doesn't reset the server state:

require 'sinatra'

GlobalState = {}
GlobalState[:some_counter] = 0

get '/' do
  response = "GlobalState[:some_counter]: #{GlobalState[:some_counter]}"
  GlobalState[:some_counter] += 1
  response
end

This code has nothing wrong: if you run it and go to http://localhost:4567 you will see GlobalState[:some_counter] incremented as expected.

But it is discouraged for the following reasons, that are mainly related to the web nature of the application:

  1. Since the data is stored in a Ruby object, if you stop the server you loose the data. however, if you don't need persistent data it's not a problem
  2. When you run a web app, usually you have simultaneous instances of your app, in order to serve multiple requests concurrently. There are a couple of ways in order to accomplish it:
    1. Forks: multiple processes of the same application. They don't share memory, so Ruby global state variables become useless
    2. Threads: threads share memory, so you can access to global state, but you have to manage concurrent accesses to the same global object, with non trivial consequences
  3. You can't associate data to the user, and vice versa: this because HTTP doesn't provides methods for state preserving (it is a stateless protocol). In order to resolve it you need either:
    1. Client-side data storing: cookies, HTML5 Local Storage...
    2. Server-side data storing: sessions (not really server-side only, you need at least to associate sessions to the respective clients, usually storing session ids into cookies)

For these reasons the web apps data management is not trivial. Anyway don't worry, you don't have to reinvent the wheel; the solutions are in hand:

  • Sinatra cookies for client-side data storing
  • Sinatra sessions for client-server data sharing
  • Databases for data persistence
like image 182
mdesantis Avatar answered Oct 08 '22 11:10

mdesantis