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
6d9eb344
Commit
6d9eb344
authored
May 13, 2021
by
Robert May
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rate-limited action caching for branches API
parent
aa389f6a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
27 deletions
+65
-27
config/feature_flags/development/api_caching_rate_limit_branches.yml
...ure_flags/development/api_caching_rate_limit_branches.yml
+8
-0
lib/api/branches.rb
lib/api/branches.rb
+31
-27
lib/api/helpers/caching.rb
lib/api/helpers/caching.rb
+26
-0
No files found.
config/feature_flags/development/api_caching_rate_limit_branches.yml
0 → 100644
View file @
6d9eb344
---
name
:
api_caching_rate_limit_branches
introduced_by_url
:
rollout_issue_url
:
milestone
:
'
13.12'
type
:
development
group
:
group::source code
default_enabled
:
false
lib/api/branches.rb
View file @
6d9eb344
...
...
@@ -38,33 +38,37 @@ module API
optional
:page_token
,
type:
String
,
desc:
'Name of branch to start the paginaition from'
end
get
':id/repository/branches'
do
user_project
.
preload_protected_branches
repository
=
user_project
.
repository
branches_finder
=
BranchesFinder
.
new
(
repository
,
declared_params
(
include_missing:
false
))
branches
=
Gitlab
::
Pagination
::
GitalyKeysetPager
.
new
(
self
,
user_project
).
paginate
(
branches_finder
)
merged_branch_names
=
repository
.
merged_branch_names
(
branches
.
map
(
&
:name
))
if
Feature
.
enabled?
(
:api_caching_branches
,
user_project
,
type: :development
,
default_enabled: :yaml
)
present_cached
(
branches
,
with:
Entities
::
Branch
,
current_user:
current_user
,
project:
user_project
,
merged_branch_names:
merged_branch_names
,
expires_in:
10
.
minutes
,
cache_context:
->
(
branch
)
{
[
current_user
&
.
cache_key
,
merged_branch_names
.
include?
(
branch
.
name
)]
}
)
else
present
(
branches
,
with:
Entities
::
Branch
,
current_user:
current_user
,
project:
user_project
,
merged_branch_names:
merged_branch_names
)
ff_enabled
=
Feature
.
enabled?
(
:api_caching_rate_limit_branches
,
user_project
,
default_enabled: :yaml
)
cache_action_if
(
ff_enabled
,
[
user_project
,
:branches
,
current_user
&
.
cache_key
,
params
],
expires_in:
30
.
seconds
)
do
user_project
.
preload_protected_branches
repository
=
user_project
.
repository
branches_finder
=
BranchesFinder
.
new
(
repository
,
declared_params
(
include_missing:
false
))
branches
=
Gitlab
::
Pagination
::
GitalyKeysetPager
.
new
(
self
,
user_project
).
paginate
(
branches_finder
)
merged_branch_names
=
repository
.
merged_branch_names
(
branches
.
map
(
&
:name
))
if
Feature
.
enabled?
(
:api_caching_branches
,
user_project
,
type: :development
,
default_enabled: :yaml
)
present_cached
(
branches
,
with:
Entities
::
Branch
,
current_user:
current_user
,
project:
user_project
,
merged_branch_names:
merged_branch_names
,
expires_in:
10
.
minutes
,
cache_context:
->
(
branch
)
{
[
current_user
&
.
cache_key
,
merged_branch_names
.
include?
(
branch
.
name
)]
}
)
else
present
(
branches
,
with:
Entities
::
Branch
,
current_user:
current_user
,
project:
user_project
,
merged_branch_names:
merged_branch_names
)
end
end
end
...
...
lib/api/helpers/caching.rb
View file @
6d9eb344
...
...
@@ -63,6 +63,32 @@ module API
body
Gitlab
::
Json
::
PrecompiledJson
.
new
(
json
)
end
# Action caching implementation
#
# This allows you to wrap an entire API endpoint call in a cache, useful
# for short TTL caches to effectively rate-limit an endpoint.
#
# @param key [Object] any object that can be converted into a cache key
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
# @return [Gitlab::Json::PrecompiledJson]
def
cache_action
(
key
,
**
cache_opts
)
json
=
cache
.
fetch
(
key
,
**
cache_opts
)
do
Gitlab
::
Json
.
dump
(
yield
.
as_json
)
end
body
Gitlab
::
Json
::
PrecompiledJson
.
new
(
json
)
end
def
cache_action_if
(
conditional
,
*
opts
)
if
conditional
cache_action
(
*
opts
)
do
yield
end
else
yield
end
end
private
# Optionally uses a `Proc` to add context to a cache key
...
...
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