Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
99acb6ae
Commit
99acb6ae
authored
Aug 19, 2021
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add store_mentions_without_subtransaction FF
Adds a feature flag to the optimization done for store_mentions!
parent
221d5414
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
94 additions
and
2 deletions
+94
-2
app/models/concerns/cache_markdown_field.rb
app/models/concerns/cache_markdown_field.rb
+33
-0
app/models/concerns/mentionable.rb
app/models/concerns/mentionable.rb
+11
-0
app/models/note.rb
app/models/note.rb
+8
-0
config/feature_flags/development/store_mentions_without_subtransaction.yml
...ags/development/store_mentions_without_subtransaction.yml
+8
-0
spec/support/shared_examples/models/mentionable_shared_examples.rb
...ort/shared_examples/models/mentionable_shared_examples.rb
+34
-2
No files found.
app/models/concerns/cache_markdown_field.rb
View file @
99acb6ae
...
...
@@ -160,6 +160,39 @@ module CacheMarkdownField
# We can only store mentions if the mentionable is a database object
return
unless
self
.
is_a?
(
ApplicationRecord
)
return
store_mentions_without_subtransaction!
if
Feature
.
enabled?
(
:store_mentions_without_subtransaction
,
default_enabled: :yaml
)
refs
=
all_references
(
self
.
author
)
references
=
{}
references
[
:mentioned_users_ids
]
=
refs
.
mentioned_user_ids
.
presence
references
[
:mentioned_groups_ids
]
=
refs
.
mentioned_group_ids
.
presence
references
[
:mentioned_projects_ids
]
=
refs
.
mentioned_project_ids
.
presence
# One retry is enough as next time `model_user_mention` should return the existing mention record,
# that threw the `ActiveRecord::RecordNotUnique` exception in first place.
self
.
class
.
safe_ensure_unique
(
retries:
1
)
do
user_mention
=
model_user_mention
# this may happen due to notes polymorphism, so noteable_id may point to a record
# that no longer exists as we cannot have FK on noteable_id
break
if
user_mention
.
blank?
user_mention
.
mentioned_users_ids
=
references
[
:mentioned_users_ids
]
user_mention
.
mentioned_groups_ids
=
references
[
:mentioned_groups_ids
]
user_mention
.
mentioned_projects_ids
=
references
[
:mentioned_projects_ids
]
if
user_mention
.
has_mentions?
user_mention
.
save!
else
user_mention
.
destroy!
end
end
true
end
def
store_mentions_without_subtransaction!
identifier
=
user_mention_identifier
# this may happen due to notes polymorphism, so noteable_id may point to a record
...
...
app/models/concerns/mentionable.rb
View file @
99acb6ae
...
...
@@ -217,6 +217,17 @@ module Mentionable
def
user_mention_association
association
(
:user_mentions
).
reflection
end
# User mention that is parsed from model description rather then its related notes.
# Models that have a description attribute like Issue, MergeRequest, Epic, Snippet may have such a user mention.
# Other mentionable models like Commit, DesignManagement::Design, will never have such record as those do not have
# a description attribute.
#
# Using this method followed by a call to *save* may result in *ActiveRecord::RecordNotUnique* exception
# in a multi-threaded environment. Make sure to use it within a *safe_ensure_unique* block.
def
model_user_mention
user_mentions
.
where
(
note_id:
nil
).
first_or_initialize
end
end
Mentionable
.
prepend_mod_with
(
'Mentionable'
)
app/models/note.rb
View file @
99acb6ae
...
...
@@ -603,6 +603,14 @@ class Note < ApplicationRecord
private
# Using this method followed by a call to *save* may result in *ActiveRecord::RecordNotUnique* exception
# in a multi-threaded environment. Make sure to use it within a *safe_ensure_unique* block.
def
model_user_mention
return
if
user_mentions
.
is_a?
(
ActiveRecord
::
NullRelation
)
user_mentions
.
first_or_initialize
end
def
system_note_viewable_by?
(
user
)
return
true
unless
system_note_metadata
...
...
config/feature_flags/development/store_mentions_without_subtransaction.yml
0 → 100644
View file @
99acb6ae
---
name
:
store_mentions_without_subtransaction
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68433
rollout_issue_url
:
milestone
:
'
14.3'
type
:
development
group
:
group::project management
default_enabled
:
false
spec/support/shared_examples/models/mentionable_shared_examples.rb
View file @
99acb6ae
...
...
@@ -207,7 +207,7 @@ RSpec.shared_examples 'an editable mentionable' do
end
RSpec
.
shared_examples
'mentions in description'
do
|
mentionable_type
|
describe
'when storing user mentions'
do
shared_examples
'when storing user mentions'
do
before
do
mentionable
.
store_mentions!
end
...
...
@@ -238,10 +238,26 @@ RSpec.shared_examples 'mentions in description' do |mentionable_type|
end
end
end
context
'when store_mentions_without_subtransaction is enabled'
do
before
do
stub_feature_flags
(
store_mentions_without_subtransaction:
true
)
end
it_behaves_like
'when storing user mentions'
end
context
'when store_mentions_without_subtransaction is disabled'
do
before
do
stub_feature_flags
(
store_mentions_without_subtransaction:
false
)
end
it_behaves_like
'when storing user mentions'
end
end
RSpec
.
shared_examples
'mentions in notes'
do
|
mentionable_type
|
context
'when mentionable notes contain mentions'
do
shared_examples
'when mentionable notes contain mentions'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user2
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
)
}
...
...
@@ -261,6 +277,22 @@ RSpec.shared_examples 'mentions in notes' do |mentionable_type|
expect
(
mentionable
.
referenced_groups
(
user
)).
to
eq
[
group
]
end
end
context
'when store_mentions_without_subtransaction is enabled'
do
before
do
stub_feature_flags
(
store_mentions_without_subtransaction:
true
)
end
it_behaves_like
'when mentionable notes contain mentions'
end
context
'when store_mentions_without_subtransaction is disabled'
do
before
do
stub_feature_flags
(
store_mentions_without_subtransaction:
false
)
end
it_behaves_like
'when mentionable notes contain mentions'
end
end
RSpec
.
shared_examples
'load mentions from DB'
do
|
mentionable_type
|
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment