Persistence in Ruby on Rails? - ruby-on-rails

Is there a way to persist data between page loads in RoR? I guess I'm looking for something like memcached, but without the overhead of TCP/IP. For example, PHP has APC.
The ideal solution would be something in memory.

Why don't you just store it in the session? The session can have multiple backends like memcache or even a database. I think it is possible to deploy memcache locally so It wouldn't matter that much.
Another posibility is to use a file backend and store it on a RAM drive. But maybe there are some memory libs for ruby which allow you to store these results directly into ram, but I got no experience with it.

cookie based session stores are wicked fast, require no serverside storage or fetching, are secure, and the Rails default. As long as the data is less than 4K no reason not to just use that.

How much data? If this is small, you could store it in the session data (i.e. session[:my_data] = "foo").

I wouldn't call the TCP/IP component "overhead" -- unless you are running the memcached server in another state or something. Memchached can be run locally just fine and rails works great with this. Perhaps memcached even has the ability to use a socket file instead of a IP and port, but I have not looked into this

You can also serialize ActiveRecord models. See the serialize method.

Related

Is there a canonical pattern for caching something related to a session on the server?

In my Rails app, once per user session, I need to have my server send a request to one of our other services to get some data about the user. I only want to make this request once per session because pinging another service every time the user makes a request will significantly slow down our response time. However, I can't store this information in a cookie client-side. This information has some security implications - if the user has the ability to lie to our server about what this piece of information is, they can gain access to data they're not authorized to see.
So what is the best way to cache or store a piece of data associated with a session on the Rails server?
I'm considering using Rails low-level caching, and I think it might even be correct:
Rails.cache.fetch(session.id, expires_in: 12.hours) do
OtherServiceAPI.get_sensitive_data(user.id)
end
I know that Rails often has one canonical way of doing things, though, so I want to be sure there's not a built-in, officially preferred way to associate a piece of data with a session. This question makes it look like there are potential pitfalls using the approach I'm considering as well, although it looks like those concerns may have been made obsolete in newer versions of Rails.
Is there a canonical pattern for what I'm trying to do? Or is the approach I'm considering idiomatic enough?

JSON Object caching in Sinatra

I have a Sinatra app in which I want to implement some caching. After the user logs in, there are about 200 DB calls to build a JSON object of things to be shown to the user, before he sees the page. That is making the performance go down quite a lot in case multiple users log in simultaneously.
I thought of using Redis, Memcachier or something similar to cache the object, and use the cache object in subsequent requests (something like this), but my teammates are not very keen on using third party services.
Is there something I can do on my own server to implement caching?
What about change your Sinatra app to Padrino, which is built on Sinatra.
I use its own cache module, it exactly fits what you want.
link here
One of my project still runs on it, and its cache stores in Redis.

How can I encrypt a cached value before storing in Rails cache (on Heroku)?

I run a live RoR (Rails 3.21.11) application on Heroku that contains some sensitive (personally-identifiable) information that we'd like to cache out (~80kb of JSON on a per-user basis).
Since we run on Heroku, we obviously trust Heroku with this data.
However, to use memcached, we need to use a Heroku addon, such as Memcachier.
The business problem: we are not willing to put this sensitive information on a third-party provider's infrastructure unless it is symmetrically encrypted on the way out.
Of course, I can do this:
value = encrypt_this(sensitive_value)
Rails.cache.write('key', value)
But we envisiage a future in which ActiveRecord objects, as well as good ol' JSON, will be stored -- so we need every bit of data going out to be automatically encrypted, and we don't want to have to write an encryption line into every bit of code that might want to use the cache.
Are there any gems/projects/tools to do this?
Although I haven't had a chance to use this yet the attr_encrypted library might get you some or all of the way there.

performance of ActiveRecord SessionStore

How big is the performance penalty switching from the cookieStore to the ActiveRecord SessionStore?
By default Ruby on Rails uses the CookieStore. But it has the disadvantage that the client needs to have its cookies enabled.
Switching to the Active SessionStore seems to solve that problem. I'm considering switching.
I read that performance is worse using the ActiveRecord SessionStore. But what is worse? Will a user notice this, or is it a matter of milliseconds? Anybody has seen benchmark results comparing the 2 options?
Any other reasons (not) to switch to the ActiveRecord SessionStore?
What is worse is that it needs to query a database, which then needs to calculate the answer, rather than going straight to the cookie on the client side.
However is it really that bad? You are correct in that the performance difference is very minuscule in most cases.
Pros:
Affinity-
If your web application ever expands to more than one server, moving your sessions to a database can allow you to run your servers without server affinity.
Security
- Since you only store the session ID on the client side, this reduces the chances of the user manipulating any data via the client side.
Cons
Performance - Instead of querying the database, you can just read the session/cookie data from the client side.
But the AR session store also depends on cookies - it saves the session id there.
As far as I know there is no way to make Rails sessions work with cookies disabled.

How to configure login when using multiple servers running a distributed service (HAProxy, Apache, Ruby on Rails)

I have 3 servers running a website. I now need to implement login system and I am having problems with it as user gets a different behavior (logged in or logged out) depending on the server it gets connected to.
I am using Memcache for session store in Rails -
config.action_controller.session_store = :mem_cache_store
ActiveSupport::Cache::MemCacheStore.new("server1","server2","server3")
I thought the second line will either keep caches in sync or something like that ...
Each server has its own db with 1 master, 2 slaves. I have tried going the route of doing sessions in sql store but that really hurts sql servers and replication load becomes really heavy.
Is there an easy way to say, use this Memcache for all session store on all 3 servers?
Will that solve my problem?
I will really appreciate it.
I haven't used memcached to store sessions before ( I feel like redis is a better solution ), but I think as long as you have the
ActiveSupport::Cache::MemCacheStore.new("server1","server2","server3")
line on each of your application servers, your sessions should stay synced up.
I've had a lot of success with just using regular cookie sessions using the same setup you've described.

Resources