BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
fb414e79
Unverified
Commit
fb414e79
authored
Dec 12, 2017
by
Yorick Peterse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Restore throttling of touch
parent
10cfd86a
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
82 additions
and
3 deletions
+82
-3
throttled_touch.rb
app/models/concerns/throttled_touch.rb
+10
-0
issue.rb
app/models/issue.rb
+1
-0
merge_request.rb
app/models/merge_request.rb
+1
-0
note.rb
app/models/note.rb
+35
-1
throttle-touching-of-objects.yml
changelogs/unreleased/throttle-touching-of-objects.yml
+5
-0
issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+1
-1
issue_spec.rb
spec/models/issue_spec.rb
+4
-0
merge_request_spec.rb
spec/models/merge_request_spec.rb
+4
-0
note_spec.rb
spec/models/note_spec.rb
+1
-1
throttled_touch.rb
spec/support/shared_examples/throttled_touch.rb
+20
-0
No files found.
app/models/concerns/throttled_touch.rb
0 → 100644
View file @
fb414e79
# ThrottledTouch can be used to throttle the number of updates triggered by
# calling "touch" on an ActiveRecord model.
module
ThrottledTouch
# The amount of time to wait before "touch" can update a record again.
TOUCH_INTERVAL
=
1
.
minute
def
touch
(
*
args
)
super
if
(
Time
.
zone
.
now
-
updated_at
)
>
TOUCH_INTERVAL
end
end
app/models/issue.rb
View file @
fb414e79
...
...
@@ -9,6 +9,7 @@ class Issue < ActiveRecord::Base
include
FasterCacheKeys
include
RelativePositioning
include
TimeTrackable
include
ThrottledTouch
include
IgnorableColumn
ignore_column
:branch_name
...
...
app/models/merge_request.rb
View file @
fb414e79
...
...
@@ -7,6 +7,7 @@ class MergeRequest < ActiveRecord::Base
include
TimeTrackable
include
ManualInverseAssociation
include
EachBatch
include
ThrottledTouch
ignore_column
:locked_at
,
:ref_fetched
...
...
app/models/note.rb
View file @
fb414e79
...
...
@@ -15,6 +15,7 @@ class Note < ActiveRecord::Base
include
IgnorableColumn
include
Editable
include
Gitlab
::
SQL
::
Pattern
include
ThrottledTouch
module
SpecialRole
FIRST_TIME_CONTRIBUTOR
=
:first_time_contributor
...
...
@@ -55,7 +56,7 @@ class Note < ActiveRecord::Base
participant
:author
belongs_to
:project
belongs_to
:noteable
,
polymorphic:
true
,
touch:
true
# rubocop:disable Cop/PolymorphicAssociations
belongs_to
:noteable
,
polymorphic:
true
# rubocop:disable Cop/PolymorphicAssociations
belongs_to
:author
,
class_name:
"User"
belongs_to
:updated_by
,
class_name:
"User"
belongs_to
:last_edited_by
,
class_name:
'User'
...
...
@@ -118,6 +119,7 @@ class Note < ActiveRecord::Base
before_validation
:set_discussion_id
,
on: :create
after_save
:keep_around_commit
,
if: :for_project_noteable?
after_save
:expire_etag_cache
after_save
:touch_noteable
after_destroy
:expire_etag_cache
class
<<
self
...
...
@@ -369,6 +371,38 @@ class Note < ActiveRecord::Base
Gitlab
::
EtagCaching
::
Store
.
new
.
touch
(
key
)
end
def
touch
(
*
args
)
# We're not using an explicit transaction here because this would in all
# cases result in all future queries going to the primary, even if no writes
# are performed.
#
# We touch the noteable first so its SELECT query can run before our writes,
# ensuring it runs on a secondary (if no prior write took place).
touch_noteable
super
end
# By default Rails will issue an "SELECT *" for the relation, which is
# overkill for just updating the timestamps. To work around this we manually
# touch the data so we can SELECT only the columns we need.
def
touch_noteable
# Commits are not stored in the DB so we can't touch them.
return
if
for_commit?
assoc
=
association
(:
noteable
)
noteable_object
=
if
assoc
.
loaded?
noteable
else
# If the object is not loaded (e.g. when notes are loaded async) we
# _only_ want the data we actually need.
assoc
.
scope
.
select
(:
id
,
:
updated_at
).
take
end
noteable_object
&
.
touch
end
def
banzai_render_context
(
field
)
super
.
merge
(
noteable:
noteable
)
end
...
...
changelogs/unreleased/throttle-touching-of-objects.yml
0 → 100644
View file @
fb414e79
---
title
:
Throttle the number of UPDATEs triggered by touch
merge_request
:
author
:
type
:
performance
spec/models/concerns/issuable_spec.rb
View file @
fb414e79
...
...
@@ -171,7 +171,7 @@ describe Issuable do
it
"returns false when record has been updated"
do
allow
(
issue
).
to
receive
(
:today?
).
and_return
(
true
)
issue
.
touch
issue
.
update_attribute
(
:updated_at
,
1
.
hour
.
ago
)
expect
(
issue
.
new?
).
to
be_falsey
end
end
...
...
spec/models/issue_spec.rb
View file @
fb414e79
...
...
@@ -765,4 +765,8 @@ describe Issue do
expect
(
described_class
.
public_only
).
to
eq
([
public_issue
])
end
end
it_behaves_like
'throttled touch'
do
subject
{
create
(
:issue
,
updated_at:
1
.
hour
.
ago
)
}
end
end
spec/models/merge_request_spec.rb
View file @
fb414e79
...
...
@@ -1852,6 +1852,10 @@ describe MergeRequest do
end
end
it_behaves_like
'throttled touch'
do
subject
{
create
(
:merge_request
,
updated_at:
1
.
hour
.
ago
)
}
end
context
'state machine transitions'
do
describe
'#unlock_mr'
do
subject
{
create
(
:merge_request
,
state:
'locked'
,
merge_jid:
123
)
}
...
...
spec/models/note_spec.rb
View file @
fb414e79
...
...
@@ -5,7 +5,7 @@ describe Note do
describe
'associations'
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
it
{
is_expected
.
to
belong_to
(
:noteable
).
touch
(
tru
e
)
}
it
{
is_expected
.
to
belong_to
(
:noteable
).
touch
(
fals
e
)
}
it
{
is_expected
.
to
belong_to
(
:author
).
class_name
(
'User'
)
}
it
{
is_expected
.
to
have_many
(
:todos
).
dependent
(
:destroy
)
}
...
...
spec/support/shared_examples/throttled_touch.rb
0 → 100644
View file @
fb414e79
shared_examples_for
'throttled touch'
do
describe
'#touch'
do
it
'updates the updated_at timestamp'
do
Timecop
.
freeze
do
subject
.
touch
expect
(
subject
.
updated_at
).
to
eq
(
Time
.
zone
.
now
)
end
end
it
'updates the object at most once per minute'
do
first_updated_at
=
Time
.
zone
.
now
-
(
ThrottledTouch
::
TOUCH_INTERVAL
*
2
)
second_updated_at
=
Time
.
zone
.
now
-
(
ThrottledTouch
::
TOUCH_INTERVAL
*
1.5
)
Timecop
.
freeze
(
first_updated_at
)
{
subject
.
touch
}
Timecop
.
freeze
(
second_updated_at
)
{
subject
.
touch
}
expect
(
subject
.
updated_at
).
to
eq
(
first_updated_at
)
end
end
end
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