diff --git a/.rubocop.yml b/.rubocop.yml index 494ce3f753d..b9f77f71b2e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,7 +11,7 @@ AllCops: Exclude: - config/initializers/forbidden_yaml.rb - app/helpers/dynamic_errors_helper.rb - - !ruby/regexp /(vendor|bundle|bin|db/(migrate/|schema\.rb)|tmp|server)($|\/.*)/ + - !ruby/regexp /(vendor|bundle|bin|db/(migrate/|schema\.rb|downloads_schema\.rb)|tmp|server)($|\/.*)/ DisplayCopNames: true DisplayStyleGuide: true TargetRubyVersion: 3.3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eed19bbf74a..9f6b28a8dac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -218,6 +218,20 @@ RSTUF_API_URL="http://localhost:80" bin/rails s When everything is set up, start the web server with `rails server` and browse to [localhost:3000](http://localhost:3000)! +#### Running with local Timescale + +There is early and experimental [TimescaleDB](https://docs.timescale.com/self-hosted/latest/) support in RubyGems.org for downloads statistics. When secondary `downloads` database is configured (using `database.yml` or by providing `DOWNLOADS_DATABASE_URL` environment variable), experimental features are automatically enabled. + +Localy, the easiest way is to run TimescaleDB using `docker-compose.yml` and configure using `database.yml.ts-sample`. + +```bash +cp config/database.yml.ts-sample config/database.yml +docker compose up -d db cache search # run required dependencies +docker compose up -d downloads-db # run optional TimescaleDB dependency +bin/rails db:setup # setup all databases, including optional Timescale one +bin/rails s # start rails server as ususal +``` + Database Layout --------------- diff --git a/Gemfile b/Gemfile index 6db035293ac..6b9d745f480 100644 --- a/Gemfile +++ b/Gemfile @@ -57,6 +57,7 @@ gem "phlex-rails", "~> 1.2" gem "discard", "~> 1.3" gem "user_agent_parser", "~> 2.18" gem "pghero", "~> 3.5" +gem "timescaledb", "~> 0.2" # Admin dashboard gem "avo", "~> 2.51" diff --git a/Gemfile.lock b/Gemfile.lock index 40c47e40377..b09f5804e65 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -702,6 +702,10 @@ GEM thor (1.3.1) tilt (2.3.0) timeout (0.4.1) + timescaledb (0.2.9) + activerecord + activesupport + pg (~> 1.2) toxiproxy (2.0.2) tpm-key_attestation (0.12.0) bindata (~> 2.4) @@ -864,6 +868,7 @@ DEPENDENCIES strong_migrations (~> 1.8) tailwindcss-rails (~> 2.6) terser (~> 1.2) + timescaledb (~> 0.2) toxiproxy (~> 2.0) unpwn (~> 1.0) user_agent_parser (~> 2.18) @@ -1139,6 +1144,7 @@ CHECKSUMS thor (1.3.1) sha256=fa7e3471d4f6a27138e3d9c9b0d4daac9c3d7383927667ae83e9ab42ae7401ef tilt (2.3.0) sha256=82dd903d61213c63679d28e404ee8e10d1b0fdf5270f1ad0898ec314cc3e745c timeout (0.4.1) sha256=6f1f4edd4bca28cffa59501733a94215407c6960bd2107331f0280d4abdebb9a + timescaledb (0.2.9) sha256=1d1382d5b889bf8ec6bcdcbf061c8e28234bc343911c81d48a9dfb22d9d5cfdc toxiproxy (2.0.2) sha256=2e3b53604fb921d40da3db8f78a52b3133fcae33e93d440725335b15974e440a tpm-key_attestation (0.12.0) sha256=e133d80cf24fef0e7a7dfad00fd6aeff01fc79875fbfc66cd8537bbd622b1e6d turbo-rails (1.5.0) sha256=b426cc762fb0940277729b3f1751a9f0bd269f5613c1d62ac73e5f0be7c7a83e diff --git a/config/database.yml.ts-sample b/config/database.yml.ts-sample new file mode 100644 index 00000000000..ceffad6f109 --- /dev/null +++ b/config/database.yml.ts-sample @@ -0,0 +1,60 @@ +default: &default + adapter: postgresql + encoding: utf8 + username: postgres + prepared_statements: false + +timescale: ×cale + adapter: postgresql + encoding: utf8 + username: postgres + migrations_paths: db/downloads_migrate + port: 5434 + +development: + primary: + <<: *default + database: rubygems_development + host: localhost + password: devpassword + pool: 5 + timeout: 5000 + downloads: + <<: *timescale + database: rubygems_tsdb_development + host: localhost + password: devpassword + pool: 5 + timeout: 5000 + +test: + primary: + <<: *default + database: rubygems_test + host: localhost + min_messages: warning + password: testpassword + pool: 5 + timeout: 5000 + downloads: + <<: *timescale + database: rubygems_tsdb_test + host: localhost + min_messages: warning + password: testpassword + pool: 5 + timeout: 5000 + +production: + primary: + <<: *default + database: rubygems_production + min_messages: error + pool: 30 + reconnect: true + downloads: + <<: *timescale + database: rubygems_tsdb_production + min_messages: error + pool: 30 + reconnect: true diff --git a/db/downloads_schema.rb b/db/downloads_schema.rb new file mode 100644 index 00000000000..c390619acd2 --- /dev/null +++ b/db/downloads_schema.rb @@ -0,0 +1,18 @@ +# 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[7.1].define(version: 0) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + enable_extension "timescaledb" + +end diff --git a/docker-compose.yml b/docker-compose.yml index afa78ad8159..3bcc4b47463 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,12 @@ services: - "5432:5432" environment: - POSTGRES_HOST_AUTH_METHOD=trust + downloads-db: + image: timescale/timescaledb:2.15.1-pg16 + ports: + - "5434:5432" + environment: + - POSTGRES_HOST_AUTH_METHOD=trust cache: image: memcached:1.4.39 ports: