Skip to content

Commit

Permalink
Merge pull request #213 from kufu/features/cache
Browse files Browse the repository at this point in the history
SolidCache
  • Loading branch information
kinoppyd authored Jan 1, 2025
2 parents c799615 + 86a9648 commit b27cba1
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 35 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ gem 'rqrcode', '~> 2.2'
gem 'rexml', '~> 3.2'

gem 'solid_queue', '~> 0.3.0'

gem 'solid_cache', '~> 1.0'
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ GEM
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
solid_cache (1.0.6)
activejob (>= 7.2)
activerecord (>= 7.2)
railties (>= 7.2)
solid_queue (0.3.4)
activejob (>= 7.1)
activerecord (>= 7.1)
Expand Down Expand Up @@ -363,6 +367,7 @@ DEPENDENCIES
rqrcode (~> 2.2)
rubocop (~> 1.18)
selenium-webdriver
solid_cache (~> 1.0)
solid_queue (~> 0.3.0)
stimulus-rails (~> 1.3)
tailwindcss-rails (~> 2.0)
Expand Down
2 changes: 1 addition & 1 deletion app/models/plan_schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class PlanSchedule < ApplicationRecord
include ActiveModel::Validations
validates_with Validators::EventEqualityValidator

belongs_to :plan
belongs_to :plan, touch: true
belongs_to :schedule

validates :memo, length: { in: 0..1024 }
Expand Down
4 changes: 4 additions & 0 deletions app/models/schedule/table.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@ def initialize(schedules, day = nil)

@rows = grouped_schedules.map { |_, v| Schedule::Table::Row.new(v) }.sort_by(&:sort_key)
end

def updated_at
@updated_at ||= rows.map(&:updated_at).max
end
end
end
4 changes: 4 additions & 0 deletions app/models/schedule/table/row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def turbo_stream_id
date = schedules[0].start_at.strftime('%Y%m%d')
[date, @start_at.sub(':', '-'), @end_at.sub(':', '-')].join('-')
end

def updated_at
@updated_at ||= schedules.map(&:updated_at).max
end
end
end
end
13 changes: 13 additions & 0 deletions app/models/schedule/tables.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,18 @@ def days
def [](key)
@map[key]
end

# Schedules::Table is the only one for each events
def id
@id ||= @schedules[0].track.event.name
end

def updated_at
@updated_at ||= @schedules.map(&:updated_at).max
end

def cache_key
"schedules/#{id}-#{updated_at.to_fs(:usec)}"
end
end
end
34 changes: 18 additions & 16 deletions app/views/schedules/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,32 @@
<% end %>
</div>
</div>
<div class="mt-4 overflow-y-auto">
<% @schedule_table.days.each do |day| %>
<div id="schedule-<%= day %>" class="schedule-table hidden">
<table class="hidden sm:table h-full w-full border-collapse border-spacing-0">
<thead>
<% cache [@schedule_table, @plan] do %>
<div class="mt-4 overflow-y-auto">
<% @schedule_table.days.each do |day| %>
<div id="schedule-<%= day %>" class="schedule-table hidden">
<table class="hidden sm:table h-full w-full border-collapse border-spacing-0">
<thead>
<th class="p-4 text-sm leading-4 border border-solid border-[rgb(214,211,208)] w-auto min-w-[184px] text-left"><%= I18n.t('table.start_end') %></th>
<% @schedule_table[day].track_list.each do |track| %>
<th class="p-4 text-sm leading-4 border border-solid border-[rgb(214,211,208)] w-auto text-center"><%= track %></th>
<% end %>
</thead>
<tbody>
</thead>
<tbody>
<% @schedule_table[day].rows.each do |row| %>
<%= render partial: 'table_row', locals: { row: row, plan: @plan, track_list: @schedule_table[day].track_list } %>
<% end %>
</tbody>
</table>
<div class="sm:hidden" id="mobile-table-<%= day %>">
<% @schedule_table[day].rows.each do |row| %>
<%= render partial: 'mobile_table_row', locals: { row: row, plan: @plan, track_list: @schedule_table[day].track_list } %>
<% end %>
</tbody>
</table>
<div class="sm:hidden" id="mobile-table-<%= day %>">
<% @schedule_table[day].rows.each do |row| %>
<%= render partial: 'mobile_table_row', locals: { row: row, plan: @plan, track_list: @schedule_table[day].track_list } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
<% end %>
</div>
<% end %>

Expand Down
17 changes: 17 additions & 0 deletions config/cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
default: &default
store_options:
# Cap age of oldest cache entry to fulfill retention policies
max_age: <%= 30.days.to_i %>
max_size: <%= 256.megabytes %>
namespace: <%= Rails.env %>

development:
database: cache
<<: *default

test:
<<: *default

production:
database: cache
<<: *default
28 changes: 19 additions & 9 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ default: &default
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
<<: *default
database: mie_development
host: "127.0.0.1"
user: postgres
port: 25432
primary: &primary_development
<<: *default
database: mie_development
host: "127.0.0.1"
user: postgres
port: 25432
cache:
<<: *primary_development
database: mie_development_cache
migrations_paths: db/cache_migrate

# The specified database role being used to connect to postgres.
# To create additional roles in postgres see `$ createuser --help`.
Expand Down Expand Up @@ -86,7 +91,12 @@ test:
# for a full overview on how database connection configuration can be specified.
#
production:
<<: *default
database: mie_production
username: mie
password: <%= ENV['MIE_DATABASE_PASSWORD'] %>
primary: &primary_production
<<: *default
database: mie_production
username: mie
password: <%= ENV['MIE_DATABASE_PASSWORD'] %>
cache:
<<: *primary_production
database: mie_production_cache
migrations_paths: db/cache_migrate
2 changes: 1 addition & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
config.active_support.report_deprecations = false

# Replace the default in-process memory cache store with a durable alternative.
# config.cache_store = :mem_cache_store
config.cache_store = :solid_cache_store

# Replace the default in-process and non-durable queuing backend for Active Job.
# config.active_job.queue_adapter = :resque
Expand Down
27 changes: 27 additions & 0 deletions db/cache_schema.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[8.0].define(version: 1) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"

create_table "solid_cache_entries", force: :cascade do |t|
t.binary "key", null: false
t.binary "value", null: false
t.datetime "created_at", null: false
t.bigint "key_hash", null: false
t.integer "byte_size", null: false
t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size"
t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size"
t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true
end
end
4 changes: 2 additions & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 17 additions & 6 deletions test/models/schedule/table/row_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
class Schedule
class Table
class RowTest < ActiveSupport::TestCase
def setup
test 'each rows mapping correct track infomations with fixture' do
schedules = events(:kaigi).schedules
@tables = Schedule::Tables.new(schedules)
end
tables = Schedule::Tables.new(schedules)

test 'each rows mapping correct track infomations with fixture' do
day1 = @tables['2024-03-18']
day1 = tables['2024-03-18']

assert_equal day1.rows[0].start_end, '10:00 - 10:30'
assert_equal day1.rows[0].tracks['TrackA'], schedules(:kaigi_day1_time1_track1)
Expand All @@ -28,7 +26,7 @@ def setup
assert_equal day1.rows[3].start_end, '11:45 - 12:30'
assert_equal day1.rows[3].tracks['TrackA'], schedules(:kaigi_day1_time4_track1)

day2 = @tables['2024-03-19']
day2 = tables['2024-03-19']

assert_equal day2.rows[0].start_end, '09:00 - 09:30'
assert_equal day2.rows[0].tracks['TrackA'], schedules(:kaigi_day2_time1_track1)
Expand All @@ -46,6 +44,19 @@ def setup
assert_equal day2.rows[3].start_end, '13:00 - 14:00'
assert_equal day2.rows[3].tracks['TrackA'], schedules(:kaigi_day2_time4_track1)
end

test '#updated_at returns newest updated at value in row' do
feature_time = Time.current.change(usec: 0) + 10.seconds

# this schedule on day1 row 0
schedules(:kaigi_day1_time1_track1).update!(updated_at: feature_time)

schedules = events(:kaigi).schedules
tables = Schedule::Tables.new(schedules)
day1 = tables['2024-03-18']

assert_equal feature_time, day1.rows[0].updated_at
end
end
end
end
13 changes: 13 additions & 0 deletions test/models/schedule/table_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,18 @@ def setup

assert_equal %w[A B], table.track_list
end

test '#updated_at returns newest updated at value in table' do
feature_time = Time.current.change(usec: 0) + 10.seconds

# this schedule on day1 row 0
schedules(:kaigi_day1_time1_track1).update!(updated_at: feature_time)

schedules = events(:kaigi).schedules
tables = Schedule::Tables.new(schedules)
@table = tables[tables.days.first]

assert_equal feature_time, @table.updated_at
end
end
end
35 changes: 35 additions & 0 deletions test/models/schedule/tables_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,40 @@ def setup
test '[] method returns Schedule::Table' do
assert_equal @tables[@tables.days.first].class, Schedule::Table
end

test '#updated_at returns newest updated at value in table' do
feature_time = Time.current.change(usec: 0) + 10.seconds

# this schedule on day1 row 0
schedules(:kaigi_day1_time1_track1).update!(updated_at: feature_time)

schedules = events(:kaigi).schedules
tables = Schedule::Tables.new(schedules)

assert_equal feature_time, tables.updated_at
end

test '#id returns schedules event name' do
assert_equal events(:kaigi).name, @tables.id
end

test '#cache_key returns cache key with cache version string' do
assert_match(%r{schedules/#{events(:kaigi).name}-\d{20}}, @tables.cache_key)
end

test 'when schedule record updated, #cache_key version string changes' do
old_key = @tables.cache_key

feature_time = Time.current.change(usec: 0) + 10.seconds

# this schedule on day1 row 0
schedules(:kaigi_day1_time1_track1).update!(updated_at: feature_time)

schedules = events(:kaigi).schedules
# rebuild
tables = Schedule::Tables.new(schedules)

refute_equal tables.cache_key, old_key
end
end
end

0 comments on commit b27cba1

Please sign in to comment.