From cda06a30be232582a7946f0dcd483299145a97e8 Mon Sep 17 00:00:00 2001 From: Mahad Kalam <55807755+skyfallwastaken@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:08:38 +0000 Subject: [PATCH] Migrate Lapse hbs + concurrent index on heartbeats' user_agent (#1056) * Add concurrent index on heartbeats user_agent * whoops, forgot to commit :skulk: --- ...0040_add_index_heartbeats_on_user_agent.rb | 7 +++++ ...1170528_update_lapse_heartbeat_language.rb | 31 +++++++++++++++++++ db/schema.rb | 3 +- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20260311170040_add_index_heartbeats_on_user_agent.rb create mode 100644 db/migrate/20260311170528_update_lapse_heartbeat_language.rb diff --git a/db/migrate/20260311170040_add_index_heartbeats_on_user_agent.rb b/db/migrate/20260311170040_add_index_heartbeats_on_user_agent.rb new file mode 100644 index 0000000..1586960 --- /dev/null +++ b/db/migrate/20260311170040_add_index_heartbeats_on_user_agent.rb @@ -0,0 +1,7 @@ +class AddIndexHeartbeatsOnUserAgent < ActiveRecord::Migration[8.1] + disable_ddl_transaction! + + def change + add_index :heartbeats, :user_agent, algorithm: :concurrently + end +end diff --git a/db/migrate/20260311170528_update_lapse_heartbeat_language.rb b/db/migrate/20260311170528_update_lapse_heartbeat_language.rb new file mode 100644 index 0000000..0022d35 --- /dev/null +++ b/db/migrate/20260311170528_update_lapse_heartbeat_language.rb @@ -0,0 +1,31 @@ +class UpdateLapseHeartbeatLanguage < ActiveRecord::Migration[8.1] + disable_ddl_transaction! + + BATCH_SIZE = 10_000 + + def up + loop do + result = execute(<<-SQL.squish) + UPDATE heartbeats + SET language = 'Lapse', updated_at = NOW() + WHERE id IN ( + SELECT id FROM heartbeats + WHERE user_agent IN ( + 'wakatime/lapse (lapse) lapse/2.0.0 lapse/2.0.0', + 'wakatime/lapse (lapse) lapse/0.1.0 lapse/0.1.0' + ) + AND language IS DISTINCT FROM 'Lapse' + LIMIT #{BATCH_SIZE} + ) + SQL + + break if result.cmd_tuples == 0 + + sleep(0.1) + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/schema.rb b/db/schema.rb index ae82063..57c8b61 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 2026_03_11_162930) do +ActiveRecord::Schema[8.1].define(version: 2026_03_11_170528) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" enable_extension "pg_stat_statements" @@ -290,6 +290,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_03_11_162930) do t.index ["project"], name: "index_heartbeats_on_project" t.index ["raw_heartbeat_upload_id"], name: "index_heartbeats_on_raw_heartbeat_upload_id" t.index ["source_type", "time", "user_id", "project"], name: "index_heartbeats_on_source_type_time_user_project" + t.index ["user_agent"], name: "index_heartbeats_on_user_agent" t.index ["user_id", "category", "time"], name: "idx_heartbeats_user_category_time", where: "(deleted_at IS NULL)" t.index ["user_id", "editor", "time"], name: "idx_heartbeats_user_editor_time", where: "(deleted_at IS NULL)" t.index ["user_id", "id"], name: "index_heartbeats_on_user_id_with_ip", order: { id: :desc }, where: "((ip_address IS NOT NULL) AND (deleted_at IS NULL))"