diff --git a/Gemfile b/Gemfile index 591d8b6..58a9818 100644 --- a/Gemfile +++ b/Gemfile @@ -41,3 +41,5 @@ group :development, :test do gem 'database_consistency' gem 'dotenv-rails' # Manage .env end + +gem "solid_cache", "~> 0.7.0" diff --git a/Gemfile.lock b/Gemfile.lock index 0ff1f88..89a89bf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -106,7 +106,7 @@ GEM code_analyzer (0.5.5) sexp_processor coderay (1.1.3) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) csv (3.3.0) @@ -151,7 +151,7 @@ GEM google-protobuf (4.27.2-x86_64-linux) bigdecimal rake (>= 13) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) importmap-rails (1.2.3) actionpack (>= 6.0.0) @@ -177,7 +177,7 @@ GEM memory_profiler (1.0.2) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.24.1) + minitest (5.25.1) mutex_m (0.2.0) net-http (0.4.1) uri @@ -191,13 +191,13 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.6-aarch64-linux) + nokogiri (1.16.7-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.6-arm64-darwin) + nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-darwin) + nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) pg (1.5.6) pg_query (5.1.0) @@ -213,7 +213,7 @@ GEM stringio puma (6.4.2) nio4r (~> 2.0) - racc (1.8.0) + racc (1.8.1) rack (3.1.7) rack-session (2.0.0) rack (>= 3.0.0) @@ -270,7 +270,7 @@ GEM rake (13.2.1) rdoc (6.7.0) psych (>= 4.0.0) - reline (0.5.9) + reline (0.5.10) io-console (~> 0.5) require_all (3.0.0) rexml (3.3.6) @@ -285,6 +285,10 @@ GEM activerecord (>= 4.0.0) railties (>= 4.0.0) sexp_processor (4.17.2) + solid_cache (0.7.0) + activejob (>= 7) + activerecord (>= 7) + railties (>= 7) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -298,7 +302,7 @@ GEM strscan (3.1.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - thor (1.3.1) + thor (1.3.2) timeout (0.4.1) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -310,7 +314,7 @@ GEM websocket-extensions (0.1.5) whenever (1.0.0) chronic (>= 0.6.3) - zeitwerk (2.6.16) + zeitwerk (2.6.18) PLATFORMS aarch64-linux @@ -352,6 +356,7 @@ DEPENDENCIES rails-pg-extras rails_best_practices scenic + solid_cache (~> 0.7.0) sprockets-rails (~> 3.4) strong_migrations whenever (~> 1.0) diff --git a/config/environments/development.rb b/config/environments/development.rb index a9c3707..cc85b93 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -18,7 +18,7 @@ config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true - config.cache_store = :memory_store + config.cache_store = :solid_cache_store config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{2.days.to_i}" } diff --git a/config/solid_cache.yml b/config/solid_cache.yml new file mode 100644 index 0000000..3f83ff1 --- /dev/null +++ b/config/solid_cache.yml @@ -0,0 +1,15 @@ +default: &default + database: <%= Rails.env %> + store_options: + max_age: <%= 1.week.to_i %> + max_size: <%= 256.megabytes %> + namespace: <%= Rails.env %> + +development: + <<: *default + +test: + <<: *default + +production: + <<: *default diff --git a/db/migrate/20240918204932_create_solid_cache_entries.solid_cache.rb b/db/migrate/20240918204932_create_solid_cache_entries.solid_cache.rb new file mode 100644 index 0000000..4ff1fbd --- /dev/null +++ b/db/migrate/20240918204932_create_solid_cache_entries.solid_cache.rb @@ -0,0 +1,12 @@ +# This migration comes from solid_cache (originally 20230724121448) +class CreateSolidCacheEntries < ActiveRecord::Migration[7.0] + def change + create_table :solid_cache_entries do |t| + t.binary :key, null: false, limit: 1024 + t.binary :value, null: false, limit: 512.megabytes + t.datetime :created_at, null: false + + t.index :key, unique: true + end + end +end diff --git a/db/migrate/20240918204933_add_key_hash_and_byte_size_to_solid_cache_entries.solid_cache.rb b/db/migrate/20240918204933_add_key_hash_and_byte_size_to_solid_cache_entries.solid_cache.rb new file mode 100644 index 0000000..32d1739 --- /dev/null +++ b/db/migrate/20240918204933_add_key_hash_and_byte_size_to_solid_cache_entries.solid_cache.rb @@ -0,0 +1,11 @@ +# This migration comes from solid_cache (originally 20240108155507) +class AddKeyHashAndByteSizeToSolidCacheEntries < ActiveRecord::Migration[7.0] + def change + safety_assured do + change_table :solid_cache_entries do |t| + t.column :key_hash, :integer, null: true, limit: 8 + t.column :byte_size, :integer, null: true, limit: 4 + end + end + end +end diff --git a/db/migrate/20240918204934_add_key_hash_and_byte_size_indexes_and_null_constraints_to_solid_cache_entries.solid_cache.rb b/db/migrate/20240918204934_add_key_hash_and_byte_size_indexes_and_null_constraints_to_solid_cache_entries.solid_cache.rb new file mode 100644 index 0000000..c28a5c1 --- /dev/null +++ b/db/migrate/20240918204934_add_key_hash_and_byte_size_indexes_and_null_constraints_to_solid_cache_entries.solid_cache.rb @@ -0,0 +1,14 @@ +# This migration comes from solid_cache (originally 20240110111600) +class AddKeyHashAndByteSizeIndexesAndNullConstraintsToSolidCacheEntries < ActiveRecord::Migration[7.0] + def change + safety_assured do + change_table :solid_cache_entries, bulk: true do |t| + t.change_null :key_hash, false + t.change_null :byte_size, false + t.index :key_hash, unique: true + t.index [:key_hash, :byte_size] + t.index :byte_size + end + end + end +end diff --git a/db/migrate/20240918204935_remove_key_index_from_solid_cache_entries.solid_cache.rb b/db/migrate/20240918204935_remove_key_index_from_solid_cache_entries.solid_cache.rb new file mode 100644 index 0000000..0a557b1 --- /dev/null +++ b/db/migrate/20240918204935_remove_key_index_from_solid_cache_entries.solid_cache.rb @@ -0,0 +1,10 @@ +# This migration comes from solid_cache (originally 20240110111702) +class RemoveKeyIndexFromSolidCacheEntries < ActiveRecord::Migration[7.0] + def change + safety_assured do + change_table :solid_cache_entries do |t| + t.remove_index :key, unique: true + end + end + end +end diff --git a/db/structure.sql b/db/structure.sql index 8da33d7..2d908f1 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -27,6 +27,9 @@ DROP INDEX IF EXISTS rideshare.index_trips_on_driver_id; DROP INDEX IF EXISTS rideshare.index_trip_requests_on_start_location_id; DROP INDEX IF EXISTS rideshare.index_trip_requests_on_rider_id; DROP INDEX IF EXISTS rideshare.index_trip_requests_on_end_location_id; +DROP INDEX IF EXISTS rideshare.index_solid_cache_entries_on_key_hash_and_byte_size; +DROP INDEX IF EXISTS rideshare.index_solid_cache_entries_on_key_hash; +DROP INDEX IF EXISTS rideshare.index_solid_cache_entries_on_byte_size; DROP INDEX IF EXISTS rideshare.index_locations_on_address; DROP INDEX IF EXISTS rideshare.index_fast_search_results_on_driver_id; ALTER TABLE IF EXISTS ONLY rideshare.vehicles DROP CONSTRAINT IF EXISTS vehicles_pkey; @@ -35,6 +38,7 @@ ALTER TABLE IF EXISTS ONLY rideshare.users DROP CONSTRAINT IF EXISTS users_pkey; ALTER TABLE IF EXISTS ONLY rideshare.trips DROP CONSTRAINT IF EXISTS trips_pkey; ALTER TABLE IF EXISTS ONLY rideshare.trip_requests DROP CONSTRAINT IF EXISTS trip_requests_pkey; ALTER TABLE IF EXISTS ONLY rideshare.trip_positions DROP CONSTRAINT IF EXISTS trip_positions_pkey; +ALTER TABLE IF EXISTS ONLY rideshare.solid_cache_entries DROP CONSTRAINT IF EXISTS solid_cache_entries_pkey; ALTER TABLE IF EXISTS ONLY rideshare.schema_migrations DROP CONSTRAINT IF EXISTS schema_migrations_pkey; ALTER TABLE IF EXISTS ONLY rideshare.vehicle_reservations DROP CONSTRAINT IF EXISTS non_overlapping_vehicle_registration; ALTER TABLE IF EXISTS ONLY rideshare.locations DROP CONSTRAINT IF EXISTS locations_pkey; @@ -46,6 +50,7 @@ ALTER TABLE IF EXISTS rideshare.users ALTER COLUMN id DROP DEFAULT; ALTER TABLE IF EXISTS rideshare.trips ALTER COLUMN id DROP DEFAULT; ALTER TABLE IF EXISTS rideshare.trip_requests ALTER COLUMN id DROP DEFAULT; ALTER TABLE IF EXISTS rideshare.trip_positions ALTER COLUMN id DROP DEFAULT; +ALTER TABLE IF EXISTS rideshare.solid_cache_entries ALTER COLUMN id DROP DEFAULT; ALTER TABLE IF EXISTS rideshare.locations ALTER COLUMN id DROP DEFAULT; DROP SEQUENCE IF EXISTS rideshare.vehicles_id_seq; DROP TABLE IF EXISTS rideshare.vehicles; @@ -57,6 +62,8 @@ DROP SEQUENCE IF EXISTS rideshare.trip_requests_id_seq; DROP TABLE IF EXISTS rideshare.trip_requests; DROP SEQUENCE IF EXISTS rideshare.trip_positions_id_seq; DROP TABLE IF EXISTS rideshare.trip_positions; +DROP SEQUENCE IF EXISTS rideshare.solid_cache_entries_id_seq; +DROP TABLE IF EXISTS rideshare.solid_cache_entries; DROP VIEW IF EXISTS rideshare.search_results; DROP TABLE IF EXISTS rideshare.schema_migrations; DROP SEQUENCE IF EXISTS rideshare.locations_id_seq; @@ -314,6 +321,39 @@ CREATE VIEW rideshare.search_results AS ORDER BY (count(t.rating)) DESC; +-- +-- Name: solid_cache_entries; Type: TABLE; Schema: rideshare; Owner: - +-- + +CREATE TABLE rideshare.solid_cache_entries ( + id bigint NOT NULL, + key bytea NOT NULL, + value bytea NOT NULL, + created_at timestamp(6) without time zone NOT NULL, + key_hash bigint NOT NULL, + byte_size integer NOT NULL +); + + +-- +-- Name: solid_cache_entries_id_seq; Type: SEQUENCE; Schema: rideshare; Owner: - +-- + +CREATE SEQUENCE rideshare.solid_cache_entries_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +-- +-- Name: solid_cache_entries_id_seq; Type: SEQUENCE OWNED BY; Schema: rideshare; Owner: - +-- + +ALTER SEQUENCE rideshare.solid_cache_entries_id_seq OWNED BY rideshare.solid_cache_entries.id; + + -- -- Name: trip_positions; Type: TABLE; Schema: rideshare; Owner: - -- @@ -491,6 +531,13 @@ ALTER SEQUENCE rideshare.vehicles_id_seq OWNED BY rideshare.vehicles.id; ALTER TABLE ONLY rideshare.locations ALTER COLUMN id SET DEFAULT nextval('rideshare.locations_id_seq'::regclass); +-- +-- Name: solid_cache_entries id; Type: DEFAULT; Schema: rideshare; Owner: - +-- + +ALTER TABLE ONLY rideshare.solid_cache_entries ALTER COLUMN id SET DEFAULT nextval('rideshare.solid_cache_entries_id_seq'::regclass); + + -- -- Name: trip_positions id; Type: DEFAULT; Schema: rideshare; Owner: - -- @@ -573,6 +620,14 @@ ALTER TABLE ONLY rideshare.schema_migrations ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version); +-- +-- Name: solid_cache_entries solid_cache_entries_pkey; Type: CONSTRAINT; Schema: rideshare; Owner: - +-- + +ALTER TABLE ONLY rideshare.solid_cache_entries + ADD CONSTRAINT solid_cache_entries_pkey PRIMARY KEY (id); + + -- -- Name: trip_positions trip_positions_pkey; Type: CONSTRAINT; Schema: rideshare; Owner: - -- @@ -635,6 +690,27 @@ CREATE UNIQUE INDEX index_fast_search_results_on_driver_id ON rideshare.fast_sea CREATE UNIQUE INDEX index_locations_on_address ON rideshare.locations USING btree (address); +-- +-- Name: index_solid_cache_entries_on_byte_size; Type: INDEX; Schema: rideshare; Owner: - +-- + +CREATE INDEX index_solid_cache_entries_on_byte_size ON rideshare.solid_cache_entries USING btree (byte_size); + + +-- +-- Name: index_solid_cache_entries_on_key_hash; Type: INDEX; Schema: rideshare; Owner: - +-- + +CREATE UNIQUE INDEX index_solid_cache_entries_on_key_hash ON rideshare.solid_cache_entries USING btree (key_hash); + + +-- +-- Name: index_solid_cache_entries_on_key_hash_and_byte_size; Type: INDEX; Schema: rideshare; Owner: - +-- + +CREATE INDEX index_solid_cache_entries_on_key_hash_and_byte_size ON rideshare.solid_cache_entries USING btree (key_hash, byte_size); + + -- -- Name: index_trip_requests_on_end_location_id; Type: INDEX; Schema: rideshare; Owner: - -- @@ -776,6 +852,10 @@ ALTER TABLE ONLY rideshare.trip_requests SET search_path TO rideshare; INSERT INTO "schema_migrations" (version) VALUES +('20240918204935'), +('20240918204934'), +('20240918204933'), +('20240918204932'), ('20231220043547'), ('20231218215836'), ('20231213045957'), diff --git a/erd.pdf b/erd.pdf index cceb3c0..218ebad 100644 Binary files a/erd.pdf and b/erd.pdf differ diff --git a/lib/patches/active_record_patches.rb b/lib/patches/active_record_patches.rb new file mode 100644 index 0000000..e425576 --- /dev/null +++ b/lib/patches/active_record_patches.rb @@ -0,0 +1,15 @@ +# +# Replace begin_db_transaction to ONLY create READ ONLY +# transactions. This would be a bad idea in a real app, which would +# need to read and write data. This is only for a demonstration. +# + +module Patches::ActiveRecordPatches + module ::ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements + def begin_db_transaction + # Replaces: + # internal_execute("BEGIN", "TRANSACTION", allow_retry: true, materialize_transactions: false) + internal_execute("BEGIN", "TRANSACTION READ ONLY", allow_retry: true, materialize_transactions: false) + end + end +end