Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add redis caching #5

Merged
merged 13 commits into from
Oct 25, 2023
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

gem 'bootsnap', require: false
gem 'pony_breeds', '~> 0.1.6'
gem 'redis', '~> 5.0'
gem 'rspec', '~> 3.0'
gem 'rspec-rails', '~> 6.0'
gem 'rswag', '~> 2.11.0'
Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ GEM
msgpack (~> 1.2)
builder (3.2.4)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crass (1.0.6)
date (3.3.3)
diff-lcs (1.5.0)
Expand Down Expand Up @@ -156,6 +157,10 @@ GEM
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
redis (5.0.8)
redis-client (>= 0.17.0)
redis-client (0.17.1)
connection_pool
regexp_parser (2.8.1)
rexml (3.2.6)
rspec (3.12.0)
Expand Down Expand Up @@ -227,6 +232,7 @@ DEPENDENCIES
pony_breeds (~> 0.1.6)
puma (~> 5.0)
rails (~> 7.0.8)
redis (~> 5.0)
rspec (~> 3.0)
rspec-rails (~> 6.0)
rswag (~> 2.11.0)
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/api/v1/pony_breeds_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require 'pony/breeds/read_pony_data'
require 'pony/breeds/redis_caching'

module Api
module V1
Expand All @@ -16,7 +17,9 @@ def random_pony
end

def pony_by_name
@result = Pony::Breeds::ReadPonyData.get_pony_by_name(params[:name])
@result = Pony::Breeds::RedisCaching.instance.cache_data("pony_by_name-#{params[:name]}") do
Pony::Breeds::ReadPonyData.get_pony_by_name(params[:name])
end

if @result.nil?
render json: "No data available for the following name: '#{params[:name]}'"
Expand All @@ -26,7 +29,9 @@ def pony_by_name
end

def pony_by_key
@result = Pony::Breeds::ReadPonyData.get_pony_by_key(params[:key])
@result = Pony::Breeds::RedisCaching.instance.cache_data("pony_by_key-#{params[:key]}") do
Pony::Breeds::ReadPonyData.get_pony_by_key(params[:key])
end

if @result.nil?
render json: "No data available for the following key: '#{params[:key]}'"
Expand Down
46 changes: 46 additions & 0 deletions app/controllers/concerns/pony/breeds/redis_caching.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

require 'singleton'

module Pony
module Breeds
class RedisCaching
include Singleton

def initialize
@redis = Redis.new(url: redis_config[:url])
@redis.ping
rescue StandardError => e
Rails.logger.error "Encountered an error while initializing Redis: '#{e.message}'."
end

def cache_data(key)
return yield unless redis_connected?

response = @redis.get(key)

if response.nil?
unless yield.nil?
@redis.setex(key, 604_800, yield.to_json)

return yield.to_json
end

return yield
end

response
end

private

def redis_config
Rails.configuration.redis
end

def redis_connected?
true if @redis.connected?
end
end
end
end
2 changes: 1 addition & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
else
config.action_controller.perform_caching = false

config.cache_store = :null_store
config.cache_store = :redis_cache_store
end

# Don't care if the mailer can't send.
Expand Down
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
config.log_tags = [:request_id]

# Use a different cache store in production.
# config.cache_store = :mem_cache_store
config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
Expand Down
6 changes: 6 additions & 0 deletions config/initializers/app_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

Rails.application.configure do
redis_config = config_for(:redis_config).symbolize_keys
config.redis = redis_config
end
11 changes: 11 additions & 0 deletions config/redis_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defaults: &base
host: <%= ENV['REDIS_HOST'] || '127.0.0.1' %>
port: <%= ENV['REDIS_PORT'] || '6379' %>
url: <%= ENV['REDIS_URL'] %>

development:
<<: *base
test:
<<: *base
production:
<<: *base