Skip to content

Commit

Permalink
reverse-proxy caching of project appraisal
Browse files Browse the repository at this point in the history
  • Loading branch information
soumyaray committed Nov 26, 2024
1 parent 3adef4d commit c75fd18
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ coverage/*
!coverage/.resultset.json
*.db
repostore/**/
_cache/
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ gem 'dry-monads', '~> 1.4'
gem 'dry-transaction', '~> 0.13'
gem 'dry-validation', '~> 1.7'

# Caching
gem 'rack-cache', '~> 1.13'
gem 'redis', '~> 4.8'
gem 'redis-rack-cache', '~> 2.2'

# DOMAIN LAYER
# Validation
gem 'dry-struct', '~> 1.0'
Expand Down
43 changes: 14 additions & 29 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,8 @@ GEM
dry-initializer (~> 3.0)
dry-schema (>= 1.12, < 2)
zeitwerk (~> 2.6)
ffi (1.17.0)
ffi (1.17.0-aarch64-linux-gnu)
ffi (1.17.0-aarch64-linux-musl)
ffi (1.17.0-arm-linux-gnu)
ffi (1.17.0-arm-linux-musl)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86-linux-gnu)
ffi (1.17.0-x86-linux-musl)
ffi (1.17.0-x86_64-darwin)
ffi (1.17.0-x86_64-linux-gnu)
ffi (1.17.0-x86_64-linux-musl)
ffi-compiler (1.3.2)
ffi (>= 1.15.5)
rake
Expand Down Expand Up @@ -109,8 +100,7 @@ GEM
rake (~> 13.0)
logger (1.6.1)
method_source (1.1.0)
mini_portile2 (2.8.8)
minitest (5.25.1)
minitest (5.25.2)
minitest-rg (5.3.0)
minitest (~> 5.0)
multi_json (1.15.0)
Expand All @@ -126,10 +116,12 @@ GEM
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (6.0.1)
puma (6.4.3)
puma (6.5.0)
nio4r (~> 2.0)
racc (1.8.1)
rack (3.1.8)
rack-cache (1.17.0)
rack (>= 0.4)
rack-session (0.3.0)
rack (>= 3.0.0.beta1)
rack-test (2.1.0)
Expand All @@ -139,6 +131,12 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
redis (4.8.1)
redis-rack-cache (2.2.1)
rack-cache (>= 1.10, < 2)
redis-store (>= 1.6, < 2)
redis-store (1.11.0)
redis (>= 4, < 6)
reek (6.3.0)
dry-schema (~> 1.13.0)
parser (~> 3.3.0)
Expand Down Expand Up @@ -188,13 +186,7 @@ GEM
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
sqlite3 (1.7.3-aarch64-linux)
sqlite3 (1.7.3-arm-linux)
sqlite3 (1.7.3-arm64-darwin)
sqlite3 (1.7.3-x86-linux)
sqlite3 (1.7.3-x86_64-darwin)
sqlite3 (1.7.3-x86_64-linux)
thor (1.3.2)
trailblazer-option (0.1.2)
Expand All @@ -209,18 +201,8 @@ GEM
zeitwerk (2.7.1)

PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
ruby
x86-linux-gnu
x86-linux-musl
x86_64-darwin
arm64-darwin-23
x86_64-linux
x86_64-linux-gnu
x86_64-linux-musl

DEPENDENCIES
dry-monads (~> 1.4)
Expand All @@ -240,9 +222,12 @@ DEPENDENCIES
pg (~> 1.2)
pry
puma (~> 6.0)
rack-cache (~> 1.13)
rack-session (~> 0.3)
rack-test
rake (~> 13.0)
redis (~> 4.8)
redis-rack-cache (~> 2.2)
reek
rerun
roar (~> 1.1)
Expand Down
45 changes: 45 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,51 @@ namespace :repos do
end
end

namespace :cache do
task :config do # rubocop:disable Rake/Desc
require_relative 'config/environment' # load config info
require_relative 'app/infrastructure/cache/redis_cache'
@api = CodePraise::App
end

desc 'Directory listing of local dev cache'
namespace :list do
desc 'Lists development cache'
task :dev do
puts 'Lists development cache'
list = `ls _cache/rack/meta`
puts 'No local cache found' if list.empty?
puts list
end

desc 'Lists production cache'
task :production => :config do
puts 'Finding production cache'
keys = CodePraise::Cache::Client.new(@api.config).keys
puts 'No keys found' if keys.none?
keys.each { |key| puts "Key: #{key}" }
end
end

namespace :wipe do
desc 'Delete development cache'
task :dev do
puts 'Deleting development cache'
sh 'rm -rf _cache/*'
end

desc 'Delete production cache'
task :production => :config do
print 'Are you sure you wish to wipe the production cache? (y/n) '
if $stdin.gets.chomp.downcase == 'y'
puts 'Deleting production cache'
wiped = CodePraise::Cache::Client.new(@api.config).wipe
wiped.each { |key| puts "Wiped: #{key}" }
end
end
end
end

desc 'Run application console'
task :console do
sh 'pry -r ./load_all'
Expand Down
10 changes: 6 additions & 4 deletions app/application/controllers/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ module CodePraise
# Web App
class App < Roda
plugin :halt
plugin :flash
plugin :all_verbs # allows DELETE and other HTTP verbs beyond GET/POST
plugin :caching
# plugin :all_verbs # allows DELETE and other HTTP verbs beyond GET/POST

# use Rack::MethodOverride # for other HTTP verbs (with plugin all_verbs)

# rubocop:disable Metrics/BlockLength
route do |routing|
response['Content-Type'] = 'application/json'

Expand All @@ -31,6 +32,8 @@ class App < Roda
routing.on String, String do |owner_name, project_name|
# GET /projects/{owner_name}/{project_name}[/folder_namepath/]
routing.get do
response.cache_control public: true, max_age: 120

path_request = Request::ProjectPath.new(
owner_name, project_name, request
)
Expand Down Expand Up @@ -86,6 +89,5 @@ class App < Roda
end
end
end
# rubocop:enable Metrics/BlockLength
end
end
22 changes: 22 additions & 0 deletions app/infrastructure/cache/redis_cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require 'redis'

module CodePraise
module Cache
# Redis client utility
class Client
def initialize(config)
@redis = Redis.new(url: config.REDIS_URL)
end

def keys
@redis.keys
end

def wipe
keys.each { |key| @redis.del(key) }
end
end
end
end
25 changes: 23 additions & 2 deletions config/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
require 'rack/session'
require 'roda'
require 'sequel'
# require 'delegate' # needed until Rack 2.3 fixes delegateclass bug
require 'rack/cache'
require 'redis-rack-cache'

module CodePraise
# Environment-specific configuration
Expand All @@ -20,13 +21,33 @@ class App < Roda
Figaro.load
def self.config = Figaro.env

configure :development, :production do
plugin :common_logger, $stderr
end

# Setup Cacheing mechanism
configure :development do
use Rack::Cache,
verbose: true,
metastore: 'file:_cache/rack/meta',
entitystore: 'file:_cache/rack/body'
end

configure :production do
use Rack::Cache,
verbose: true,
metastore: "#{config.REDISCLOUD_URL}/0/metastore",
entitystore: "#{config.REDISCLOUD_URL}/0/entitystore"
end

# Automated HTTP stubbing for testing only
configure :app_test do
require_relative '../spec/helpers/vcr_helper'
VcrHelper.setup_vcr
VcrHelper.configure_vcr_for_github(recording: :none)
end

# Database Setup
# Database Setup (ensure DATABASE_URL already configured on production)
configure :development, :test, :app_test do
require 'pry'; # for breakpoints
ENV['DATABASE_URL'] = "sqlite://#{config.DB_FILENAME}"
Expand Down
4 changes: 4 additions & 0 deletions config/secrets_example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ development:
GITHUB_TOKEN: create_github_token
REPOSTORE_PATH: repostore
API_HOST: http://localhost:9090
REDISCLOUD_URL: url-assigned-by-Redis-provider-on-Heroku

app_test:
DB_FILENAME: db/local/test.db
REPOSTORE_PATH: repostore
API_HOST: http://localhost:9090
REDISCLOUD_URL: url-assigned-by-Redis-provider-on-Heroku

test:
DB_FILENAME: db/local/test.db
GITHUB_TOKEN: create_github_token
REPOSTORE_PATH: repostore
API_HOST: http://localhost:9090
REDISCLOUD_URL: url-assigned-by-Redis-provider-on-Heroku

production:
# - assign DATABASE_URL in production
GITHUB_TOKEN: create_github_token
REPOSTORE_PATH: repostore
API_HOST: https://codepraise2022-api
REDISCLOUD_URL: url-assigned-by-Redis-provider-on-Heroku

0 comments on commit c75fd18

Please sign in to comment.