diff --git a/app/models/event.rb b/app/models/event.rb index e855ed02274aec451a1043fa70f9c842475fa71c..166c3f1b4b15f0c0c73759d4a7b144d84c35ff6d 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -65,7 +65,7 @@ class Event < ActiveRecord::Base # Callbacks after_create :reset_project_activity after_create :set_last_repository_updated_at, if: :push? - after_create :track_user_contributed_projects + after_create :track_user_interacted_projects # Scopes scope :recent, -> { reorder(id: :desc) } @@ -391,10 +391,10 @@ class Event < ActiveRecord::Base .update_all(last_repository_updated_at: created_at) end - def track_user_contributed_projects + def track_user_interacted_projects # Note the call to .available? is due to earlier migrations # that would otherwise conflict with the call to .track # (because the table does not exist yet). - UserContributedProjects.track(self) if UserContributedProjects.available? + UserInteractedProjects.track(self) if UserInteractedProjects.available? end end diff --git a/app/models/user_contributed_projects.rb b/app/models/user_interacted_projects.rb similarity index 92% rename from app/models/user_contributed_projects.rb rename to app/models/user_interacted_projects.rb index 624d41e35267c066c91985969dc86df1164ee565..ba6ed2bd2ffd40e93f08b395f8a0de3ceefd6154 100644 --- a/app/models/user_contributed_projects.rb +++ b/app/models/user_interacted_projects.rb @@ -1,4 +1,4 @@ -class UserContributedProjects < ActiveRecord::Base +class UserInteractedProjects < ActiveRecord::Base belongs_to :user belongs_to :project @@ -52,7 +52,7 @@ class UserContributedProjects < ActiveRecord::Base private def cached_exists?(project_id:, user_id:, &block) - cache_key = "user_contributed_projects:#{project_id}:#{user_id}" + cache_key = "user_interacted_projects:#{project_id}:#{user_id}" Rails.cache.fetch(cache_key, expires_in: CACHE_EXPIRY_TIME, &block) end end diff --git a/changelogs/unreleased/43460-track-projects-a-user-contributed-to.yml b/changelogs/unreleased/43460-track-projects-a-user-contributed-to.yml deleted file mode 100644 index 96bf941aec5800d127d717f208ef2ee1968fa4ea..0000000000000000000000000000000000000000 --- a/changelogs/unreleased/43460-track-projects-a-user-contributed-to.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Keep track of projects a user contributed to. -merge_request: 17327 -author: -type: other diff --git a/changelogs/unreleased/43460-track-projects-a-user-interacted-with.yml b/changelogs/unreleased/43460-track-projects-a-user-interacted-with.yml new file mode 100644 index 0000000000000000000000000000000000000000..99b6ac76a3ec50353176f946df8fbca0e812e7bf --- /dev/null +++ b/changelogs/unreleased/43460-track-projects-a-user-interacted-with.yml @@ -0,0 +1,5 @@ +--- +title: Keep track of projects a user interacted with. +merge_request: 17327 +author: +type: other diff --git a/db/migrate/20180223120443_create_user_contributed_projects_table.rb b/db/migrate/20180223120443_create_user_contributed_projects_table.rb deleted file mode 100644 index 2f7b6c578c378cfabd06d1d63ffce2e6241e5c60..0000000000000000000000000000000000000000 --- a/db/migrate/20180223120443_create_user_contributed_projects_table.rb +++ /dev/null @@ -1,21 +0,0 @@ -class CreateUserContributedProjectsTable < ActiveRecord::Migration - include Gitlab::Database::MigrationHelpers - - DOWNTIME = false - - disable_ddl_transaction! - - def up - create_table :user_contributed_projects, id: false do |t| - t.references :user, null: false - t.references :project, null: false - end - - add_concurrent_foreign_key :user_contributed_projects, :users, column: :user_id, on_delete: :cascade - add_concurrent_foreign_key :user_contributed_projects, :projects, column: :project_id, on_delete: :cascade - end - - def down - drop_table :user_contributed_projects - end -end diff --git a/db/migrate/20180223120443_create_user_interacted_projects_table.rb b/db/migrate/20180223120443_create_user_interacted_projects_table.rb new file mode 100644 index 0000000000000000000000000000000000000000..8089de45666c8218ac1ea558b4084f10d510af3c --- /dev/null +++ b/db/migrate/20180223120443_create_user_interacted_projects_table.rb @@ -0,0 +1,21 @@ +class CreateUserInteractedProjectsTable < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + create_table :user_interacted_projects, id: false do |t| + t.references :user, null: false + t.references :project, null: false + end + + add_concurrent_foreign_key :user_interacted_projects, :users, column: :user_id, on_delete: :cascade + add_concurrent_foreign_key :user_interacted_projects, :projects, column: :project_id, on_delete: :cascade + end + + def down + drop_table :user_interacted_projects + end +end diff --git a/db/post_migrate/20180223124427_build_user_contributed_projects_table.rb b/db/post_migrate/20180223124427_build_user_interacted_projects_table.rb similarity index 64% rename from db/post_migrate/20180223124427_build_user_contributed_projects_table.rb rename to db/post_migrate/20180223124427_build_user_interacted_projects_table.rb index ede130a3fbf91a045578e98856bb977d3ce301c4..0992509c629c306f96c92fb06b8e642d2d3a06f2 100644 --- a/db/post_migrate/20180223124427_build_user_contributed_projects_table.rb +++ b/db/post_migrate/20180223124427_build_user_interacted_projects_table.rb @@ -1,4 +1,4 @@ -class BuildUserContributedProjectsTable < ActiveRecord::Migration +class BuildUserInteractedProjectsTable < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers # Set this constant to true if this migration requires downtime. @@ -13,13 +13,13 @@ class BuildUserContributedProjectsTable < ActiveRecord::Migration MysqlStrategy.new end.up - add_concurrent_index :user_contributed_projects, [:project_id, :user_id], unique: true + add_concurrent_index :user_interacted_projects, [:project_id, :user_id], unique: true end def down - execute "TRUNCATE user_contributed_projects" + execute "TRUNCATE user_interacted_projects" - remove_concurrent_index_by_name :user_contributed_projects, 'index_user_contributed_projects_on_project_id_and_user_id' + remove_concurrent_index_by_name :user_interacted_projects, 'index_user_interacted_projects_on_project_id_and_user_id' end private @@ -31,22 +31,22 @@ class BuildUserContributedProjectsTable < ActiveRecord::Migration SLEEP_TIME = 5 def up - with_index(:events, [:author_id, :project_id], name: 'events_user_contributions_temp', where: 'project_id IS NOT NULL') do + with_index(:events, [:author_id, :project_id], name: 'events_user_interactions_temp', where: 'project_id IS NOT NULL') do iteration = 0 records = 0 begin - Rails.logger.info "Building user_contributed_projects table, batch ##{iteration}" + Rails.logger.info "Building user_interacted_projects table, batch ##{iteration}" result = execute <<~SQL - INSERT INTO user_contributed_projects (user_id, project_id) + INSERT INTO user_interacted_projects (user_id, project_id) SELECT e.user_id, e.project_id FROM (SELECT DISTINCT author_id AS user_id, project_id FROM events WHERE project_id IS NOT NULL) AS e - LEFT JOIN user_contributed_projects ucp USING (user_id, project_id) + LEFT JOIN user_interacted_projects ucp USING (user_id, project_id) WHERE ucp.user_id IS NULL LIMIT #{BATCH_SIZE} SQL iteration += 1 records += result.cmd_tuples - Rails.logger.info "Building user_contributed_projects table, batch ##{iteration} complete, created #{records} overall" + Rails.logger.info "Building user_interacted_projects table, batch ##{iteration} complete, created #{records} overall" Kernel.sleep(SLEEP_TIME) if result.cmd_tuples > 0 rescue ActiveRecord::InvalidForeignKey => e Rails.logger.info "Retry on InvalidForeignKey: #{e}" @@ -54,7 +54,7 @@ class BuildUserContributedProjectsTable < ActiveRecord::Migration end while result.cmd_tuples > 0 end - execute "ANALYZE user_contributed_projects" + execute "ANALYZE user_interacted_projects" end @@ -73,10 +73,10 @@ class BuildUserContributedProjectsTable < ActiveRecord::Migration def up execute <<~SQL - INSERT INTO user_contributed_projects (user_id, project_id) + INSERT INTO user_interacted_projects (user_id, project_id) SELECT e.user_id, e.project_id FROM (SELECT DISTINCT author_id AS user_id, project_id FROM events WHERE project_id IS NOT NULL) AS e - LEFT JOIN user_contributed_projects ucp USING (user_id, project_id) + LEFT JOIN user_interacted_projects ucp USING (user_id, project_id) WHERE ucp.user_id IS NULL SQL end diff --git a/db/schema.rb b/db/schema.rb index 8366957f69165091fca5637ad0d91f923929b17b..b94c8af273aae1c3524ca2d39ae5fbd3dba29bda 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1815,13 +1815,6 @@ ActiveRecord::Schema.define(version: 20180304204842) do add_index "user_callouts", ["user_id", "feature_name"], name: "index_user_callouts_on_user_id_and_feature_name", unique: true, using: :btree add_index "user_callouts", ["user_id"], name: "index_user_callouts_on_user_id", using: :btree - create_table "user_contributed_projects", id: false, force: :cascade do |t| - t.integer "user_id", null: false - t.integer "project_id", null: false - end - - add_index "user_contributed_projects", ["project_id", "user_id"], name: "index_user_contributed_projects_on_project_id_and_user_id", unique: true, using: :btree - create_table "user_custom_attributes", force: :cascade do |t| t.datetime_with_timezone "created_at", null: false t.datetime_with_timezone "updated_at", null: false @@ -1833,6 +1826,13 @@ ActiveRecord::Schema.define(version: 20180304204842) do add_index "user_custom_attributes", ["key", "value"], name: "index_user_custom_attributes_on_key_and_value", using: :btree add_index "user_custom_attributes", ["user_id", "key"], name: "index_user_custom_attributes_on_user_id_and_key", unique: true, using: :btree + create_table "user_interacted_projects", id: false, force: :cascade do |t| + t.integer "user_id", null: false + t.integer "project_id", null: false + end + + add_index "user_interacted_projects", ["project_id", "user_id"], name: "index_user_interacted_projects_on_project_id_and_user_id", unique: true, using: :btree + create_table "user_synced_attributes_metadata", force: :cascade do |t| t.boolean "name_synced", default: false t.boolean "email_synced", default: false @@ -2101,9 +2101,9 @@ ActiveRecord::Schema.define(version: 20180304204842) do add_foreign_key "trending_projects", "projects", on_delete: :cascade add_foreign_key "u2f_registrations", "users" add_foreign_key "user_callouts", "users", on_delete: :cascade - add_foreign_key "user_contributed_projects", "projects", name: "fk_6fe26e92ae", on_delete: :cascade - add_foreign_key "user_contributed_projects", "users", name: "fk_285db038d3", on_delete: :cascade add_foreign_key "user_custom_attributes", "users", on_delete: :cascade + add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade + add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade add_foreign_key "user_synced_attributes_metadata", "users", on_delete: :cascade add_foreign_key "users_star_projects", "projects", name: "fk_22cd27ddfc", on_delete: :cascade add_foreign_key "web_hook_logs", "web_hooks", on_delete: :cascade diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 445de37d2b1bb70199fee626d31a6b6f51130dc5..780eacbb8dcd986d0c0ee7474347216e6b0f2101 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -50,18 +50,18 @@ describe Event do end end - describe 'after_create :track_user_contributed_projects' do + describe 'after_create :track_user_interacted_projects' do let(:event) { build(:push_event, project: project, author: project.owner) } - it 'passes event to UserContributedProjects.track' do - expect(UserContributedProjects).to receive(:available?).and_return(true) - expect(UserContributedProjects).to receive(:track).with(event) + it 'passes event to UserInteractedProjects.track' do + expect(UserInteractedProjects).to receive(:available?).and_return(true) + expect(UserInteractedProjects).to receive(:track).with(event) event.save end - it 'does not call UserContributedProjects.track if its not yet available' do - expect(UserContributedProjects).to receive(:available?).and_return(false) - expect(UserContributedProjects).not_to receive(:track) + it 'does not call UserInteractedProjects.track if its not yet available' do + expect(UserInteractedProjects).to receive(:available?).and_return(false) + expect(UserInteractedProjects).not_to receive(:track) event.save end end diff --git a/spec/models/user_contributed_projects_spec.rb b/spec/models/user_interacted_projects_spec.rb similarity index 98% rename from spec/models/user_contributed_projects_spec.rb rename to spec/models/user_interacted_projects_spec.rb index 092821c8aeaf5199bad2db80ffcad0123f761d77..503d89e7f86d216da898c8aa729fa072689e56d4 100644 --- a/spec/models/user_contributed_projects_spec.rb +++ b/spec/models/user_interacted_projects_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe UserContributedProjects do +describe UserInteractedProjects do describe '.track' do subject { described_class.track(event) } let(:event) { build(:event) }