Rails caching with memcached, get not working - ruby-on-rails

I have come into an existing Rails project which claims to use memcached. As a test I tried putting an object in the cache with
Rails.cache.write("gateway", #gateway)
Then retrieving it with
Rails.cache.read("gateway", #gateway)
however this returns nil, why is this?
This is in a development environment, memcached is installed and running and should be enabled by the entries config.cache_classes = true and config.action_controller.perform_caching = true.

Rails projects use memcached in various different ways but if you are working on a rails 3 project then I would suggest they may be using the 'dalli' gem which uses a memcached session store. So using the cache could instead be done something like this session[:gateway] = #gateway and the opposite #gateway = session[:gateway] the other way it is done is memcache.set('gateway',#gateway') and memcache.get('gateway')
Would be helpful to see the configuration code. check /config/initializers/session_store.rb for something like Rails.application.config.session_store :dalli_store ............
Also as said in the comments if you are in development caching may be turned off. Check your config/development.rb file for the following:
config.action_controller.perform_caching = false
the other thing is you need to have memcached installed on your os for linux this is sudo apt-get install memcached and can be checked by ps aux | grep memcache (this should show two proccesses the grep and memcache)
Update
Should also check out the rails caching guide

Related

Rails server start up time is very slow with upgrade

I am trying to upgrade rails app from v3 to v4. In v3, the server start time is less than a minute. but in v4, it is taking more than 30 mins. In logs, i can see that for each server start,
1/10 preloading assets...
2/10 preloading assets...
.
.
10/10 preloading aseets...
done
is being logged and this is the part taking up 99% of the time. I believe assets are being compiled every time while loading the classes. could someone please let me know which config is causing this ?
I have tried most of the suggested solutions related to asset config in stackoverflow but doesnt seem to get resolved.
current config:
config.cache_classes = false
config.eager_load = false
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.reload_classes_only_on_change = true
config.assets.digest = false
config.assets.debug = false
config.assets.compress = false
The best way to tackle this is to profile your app startup. There are several ways that you can take, some fairly technical, but not invasive (e.g. using DTrace), others more invasive, but easier to do (e.g. monkeypatch require).
This page contains a couple of relevant sources: https://waynechu.cc/posts/196-profiling-rails-boot-time. I'd be surprised if none of the options proposed there help.
Another option can be found here: https://gist.github.com/robdimarco/e610b2b5c31c68bb13fe
The IMO easiest way to use this is as follows:
add ruby-prof to your Gemfile and run bundle install
boot an irb shell with it: bundle exec irb -rruby-prof
run the code from the snippet in the irb shell
The output there should give you a good indication where to start looking.
Thanks for pitching in folks. Just now, got it resolved.
I am using turbo-sprockets-rails-4 in which preload assets is enabled by default for dev environments.
added below config in config/environments/development.rb
TurboSprockets.configure do |config|
config.preloader.enabled = false
end
now server startup time is as fast as rails3
this is mentioned in their readme itself, but missed it while skimming through

How can I clear rails action cache? (Rails.cache.clear isn't working)

How can I clear rails action cache without restarting the server?
I have a script that updates the Postgres database with new data. I'd like to clear all cached pages after the script completes. but I can't seem to get this to take effect without completely restarting the Heroku server
I have tried without success:
Rails.cache.clear => ["/app/tmp/cache/bootsnap-compile-cache", "/app/tmp/cache/bootsnap-load-path-cache"]
rails tmp:cache:clear
rails assets:clean
config.cache_store is not set explicitly for production, (I've seen mixed information as to what cache is being used by default)
I have ensured that there is no caching in the browser (by disabling caching in dev tools and bypassing the service worker)
I'm using Heroku with ruby 2.5.3, rails 5.2.1.1, and actionpack-action_caching 1.2.0
How do I know it's not being cached at the database layer or with Fragment Caching?
I added logging to the action which only logs the first time a page is accessed after a restart
Update: I removed action caching and instead better optimized the SQL quarries by using eager loading.
Update 2 (writing in retrospect)
I didn't properly understand how Heroku's dyno's work.
Heroku spines up new VM's (dynos) when using heroku run bash, causing any cache clearing not to affect the webserver running on the existing dyno. To ssh into running dynos you'll want to use heroku ps:exec
As you can see here, default cache store in production is mem_cache_store. Therefore, you should be able to clear it in different ways, without restarting the sever. Maciej Mensfeld wrote a blog about these ways. I personally use flush_all command in the cache server if Rails.cache.clear does not make effect.

How to setup dalli cache in test environment?

I'm going to use Dalli cache as key-value store.
Usually in production and development environments we have line
config.cache_store = :dalli_store
so then we can use Rails.cache construction to read from and write to cache.
But in the test environment usually, we don't have this config line.
What is the right way to set up a cache in a test environment in purpose to test my storing logic?
P.S. I'm using Linux(Ubuntu)
dalli is a client for the caching service (memcached)
set it globally whatever the environment, ie in your config/application.rb
config.cache_store = :dalli_store
caching being deactivated in the test environment is a common approach, check config/environments/test.rb
config.action_controller.perform_caching = false
so you can enable it for the test environment, but it could lead to some weird conflicts
best is probably to enable it on the go for a specific specs only:
before do # enable caching
#caching_state = ActionController::Base.perform_caching
ActionController::Base.perform_caching = true
end
after do # disable caching
ActionController::Base.perform_caching = #caching_state
end
I have assumed you are on Ubuntu and did a google of "ubuntu install memcached rails" and found several pages with details. Below are the key points.
To Install memecache
sudo apt-get install memcached
To restart memcahce
/etc/init.d/memcached restart

Rails 3.1 application deployment tutorial

I'm looking for a good deployment tutorial for a Rails 3.1.1 application on a server. And by good I actually mean complete. The reason I'm posting this question is that although there are tons of tutorials out there on the web (google, blogs, books, other stackoverflow questions etc...) all of them seem to focus either on a problem with the deployment process or make some assumptions about the deployment environment that do not match with what I need.
I realize that deploying a Rails app on a server requieres a variety of different programs and tools that need to be configured and somehow I always get stuck on apparently "little" things that make me very frustrated.
So, let's begin from the start. What I have now is a server that I can access through SSH and a domain name, let's call it www.example.com. The server runs a fresh Ubuntu 10.04 x64 and has just a user installed, namely root (through root I access the server with SSH).
Note! There is no Apache, Ruby, PHP, MySQL, cPanel or any other panel installed, just the bare minimum that comes with a fresh installation.
Also the web server will host a single application and the database will run on the same machine.
From my knowledge the process of deploying a Rails application follows the following scenarios:
Installing Ruby
I already did this by using RVM using the Multi-User install process (simply because I have just the root user and it does it automatically). This seems to work fine aftewards but I do have some questions:
Would it make more sense to install Ruby directly and not through RVM (I'm thinking maybe in terms of efficiency - also RVM does a little bit of magic behind the scences modifying some bash_profile files in ways that I don't understand and this somehow seems invasive...)?
Would it make more sense to install as a separate user through RVM (can there any safety problems arise)?
Necessary gems
Now that Ruby is installed what would be the best initial set of gems to install along side it?
I installed just bundler, so that once I upload my application on the server I can run a bundle install command which will install in turn the required app gems.
Question - Should I install the rails gem before hand? Are there any other gems that need to be installed?
Web server
This is where it gets tricky for me. I'm trying to use apache and mod-passenger for deployment (they seem to be the most popular). So I installed the apache web server and the passenger gem and all the related dependencies (libraries mentioned by passenger).
Now, the problems arise. First thing is user related. How does Apache run? I mean under each user? If I installed it and (re)started it using the root user, will it permanently run under the root user? Is this a bad thing? If yes, should I create another user? If yes, how? In what groups should I put the new user in, what rights should he have (namely what folders should he have access to). How to start the apache in this case (under root, under that user, add a line somewhere in the configuration file, etc.)
Website configuration
Where to put the website configuration stuff? Is it OK to put it into apache.conf, or should I create a new file in sites-available? Or should I simply reuse the default file that is already present there? If a new user has been created at the previous step, what rights should he have in relation to the config files?
Also... where to eventually put the rails application? In what folder would it be best? Somewhere under home? Maybe under /var/www? I want to know how would this affect the rights of the apache process serving the app? (Generally I have problems while serving an app, it complains that it doesn't have rights on a specific folder. Also, using the new asset pipelines - which I don't fully understand - asset files are being created and they seem not to inherit the parent folder rights...)
Database
As database I'm using MySQL and installing it is pretty straightforward. The question that I have here is again user related. Should I use a special user for the database? How does MySQL actually manage users (are they internal, or are they the Linux users or ...?). Should the database user be the same as the "web user" from above? Or should it be a different one?
Assets
Here I get really lost. I really have troubles making the assets pipeline works. I've checked the railscasts episode and also the rails website tutorial and I do seem to theoretically understand the thing, yet I have problems in practice.
So the questions here would be - what commands should I run to precompile the assets? (Trying to run rake assets:precompile). Is it ok? What should I change in the production.rb file? How do the assets generated work in relation with the webuser or database users created above? I am personally getting a problem in this step namely the log files say that some css files are not accessible (for example I have jqplot library installed under the vendor/assets folder and its files cannot be accessed - should I add a manifest file here somehow?).
It would be really great if someone could point me towards a nice article, or resource that explains all this stuff. The main area which I'm having problems in is how does Apache, Passenger, Ruby, Rails and MySQL interact with a Linux user. How to properly set up the permissions for the Rails app folder? How does the assets pipeline affect this user permission stuff?
Thank you
Here's my way of deploying Rails:
Installing Ruby
I would not use RVM because it's very tricky to get it running properly in combination with stuff like cron jobs. Doable (with wrappers for example), but a bit of a hassle. If you don't need other Ruby versions on that machine, just install it from source yourself.
Gems
Just let Bundler work its magic. Remember to install with the flags --without test development --deployment. I wouldn't do that up front though. Just make sure you have bundler.
Web server
Using Passenger (with either Apache or Nginx) is a fine and easy choice. When you install Apache from apt, it will run in a special user.
Apache is configured correctly automatically on Ubuntu. It will start on reboot.
Website configuration
All configuration be in /etc/apache2. Place your virtual host configuration in /etc/apache2/sites-available and use a2ensite to enable it.
Put your app in /var/www, since that is the default location in Ubuntu. I usually make a deploy user.
Make sure that user can access your application by assigning your app to the www-data group.
Database
MySQL has its own user system. Log in as root user and create a new user with SQL: GRANT ALL ON 'application_production'.* TO 'deploy' IDENTIFIED BY 'some password';
Assets
Assets should be generated as the user owning the application. You should add any css and javascript files to production.rb. For example:
config.assets.precompile += %w(backend.css)
Conclusion
It helps to use a deploy tool like Capistrano. When you run capify, uncomment the appropriate line in the Capfile to get assets compilation. Here's mine:
ENV['RAILS_ENV'] = 'production'
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
load 'deploy/assets'
load 'config/deploy'
require 'capistrano/ext/multistage'
require "bundler/capistrano"
require 'capistrano_colors'
This is just how I normally install my rails apps. I hope this will get you going. Recently I've written a gem for integrating Chef-solo with Capistrano, called capistrano-chef-solo. It's very alpha and might be a bit too complicated if you're just starting with deployment, but it might help you.

Rails 3: how to detect if the application is running in server mode for multiple different environment?

I have an app that runs on multiple servers:
- locally on dev machines
- on heroku
- on a specific server with Passanger on Nginx
I am trying to launch a particular code (loading some REDIS keys) that is only required if the web server is launched.
I have done quite a bit of digging, and the nicest solution I found was to execute my code in an initializer with:
if defined?(Rails::Server)
#my code
end
This works well locally, but it seems that Rails::Server never gets defined either on Heroku or Passanger.
I need a solution that works in every case, please help, this is really important.
Thanks,
Alex
ps: I am running Rails 3.0.4, Ruby 1.8.7
Putting code in your config.ru file might be a more robust way of detecting server mode across different types of servers (Unicorn/Passenger/Rails::Server/etc).
e.g., in rails-root/config.ru:
# This file is used by Rack-based servers to start the application.
# ADD this line and read the value later:
ENV['server_mode'] = '1'
require ::File.expand_path...
What about?
config.serve_static_assets = ( defined?(Mongrel) || defined?(WEBrick) ) ? true : false

Resources