Leonard Kakande
Leonard Kakande

Reputation: 695

arrays as global variables in sinatra

Hello i would like to have arrays store something then i access it to fill some data in the database, i would like to know how to do this, and also how to declare them as global, you may explain using the code below

I want to use the arrays to store some data, then put that data in the database, but i seen not to be able to do that: I am using DataMapper also

the two post method have to access those global arrays that is what i need to figure out. thanks ( I am sinatra newbie)

module Scanner
  class SellItemApp < Scanner::Base

    configure do
      set :in_customer,[] #to be used in adding multiple items
      set :items, [] #to be used in adding multiple items
    end

    get '/something' do
      erb :sale_records
    end

    post '/something1' do
      .........
    end

    post 'something2' do
    .....

    end

  end
end

Upvotes: 0

Views: 575

Answers (2)

Uri Agassi
Uri Agassi

Reputation: 37419

Configuration is meant for static data, which is not changed in the life of the application, and not part of its state.

Using configuration to cache data between requests is not a good idea for several reasons:

  • Global data is not insulated - when a user adds an 'item' in your app all other users will see it, since it is stored globally...
  • In-memory data is not scalable - this solution might work as long as you run a single sinatra instance on a single machine. At the moment your application needs to scale, either by adding machines, or even by using multiple processes (in a passenger or unicorn containers) - data changes in one process/machine is not populated to other processes/machines - and it won't be consistent.
  • Not thread safe - even if you scale by making you application multi-threaded, you'll just be entering the world of pain of race-conditions and synchronization blocks
  • It is not persistent - if your process fails for some reason - all of its state is lost.

So, what should you do? There are a couple of options, depending on your requirements - should the data for shared by all users, or insulated between users? Should it be persistent over time?

  • If the data is in the scope of the user, and should be kept only for the current session, you can use cookies to save your data, using Sinatra's sessions
  • If the data is global, should be kept for availability, but if data is lost it is not a catastrophe - you can use memcached
  • If the data should be kept for a long time, you should seriously consider persisting it. It doesn't have to be mapped by ActiveRecord or DataMapper, depending on the complexity of your data. It doesn't even have to be persisted to a relational database like mysql, some noSql options like redis, couchbase, etc. can be easily added to your ruby project.

Upvotes: 2

Patru
Patru

Reputation: 4551

Well, if I understand Leonard correctly he wants to access some "configuration" variables he intends to use as makeshift database. Quoting from the Sinatra documentation there is

set :foo, 'bar'
set :baz, Proc.new { "Hello " + foo }

get '/baz' do
  "baz is set to " + settings.baz
end

and I guess (have not tried it) you might stuff your things into it if you like. Note however that this will be lost if you restart your server (should carry over for multiple requests though).

If you want your "stored data" to survive a server restart DataMapper is of course the right solution. See the corresponding docs on how to do it. It is probably not a good idea to use a configuration mechanism for any kind of data "storage".

Upvotes: 0

Related Questions