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
38c24212
Unverified
Commit
38c24212
authored
Feb 04, 2018
by
Matija Čupić
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor runner attribute caching implementation
parent
28fd49c1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
44 deletions
+61
-44
runner.rb
app/models/ci/runner.rb
+44
-27
runner.rb
lib/api/helpers/runner.rb
+1
-1
runner_spec.rb
spec/models/ci/runner_spec.rb
+16
-16
No files found.
app/models/ci/runner.rb
View file @
38c24212
...
...
@@ -5,7 +5,7 @@ module Ci
RUNNER_QUEUE_EXPIRY_TIME
=
60
.
minutes
ONLINE_CONTACT_TIMEOUT
=
1
.
hour
UPDATE_DB_RUNNER_INFO_EVERY
=
1
.
hour
UPDATE_DB_RUNNER_INFO_EVERY
=
40
.
minutes
AVAILABLE_SCOPES
=
%w[specific shared active paused online]
.
freeze
FORM_EDITABLE
=
%i[description tag_list active run_untagged locked access_level]
.
freeze
...
...
@@ -68,12 +68,20 @@ module Ci
ONLINE_CONTACT_TIMEOUT
.
ago
end
def
cached_contacted_at
if
runner_info_cache
(
:contacted_at
)
Time
.
zone
.
parse
(
runner_info_cache
(
:contacted_at
))
else
self
.
contacted_at
end
def
contacted_at
cached_attribute
(
:contacted_at
)
||
read_attribute
(
:contacted_at
)
end
def
version
cached_attribute
(
:version
)
||
read_attribute
(
:version
)
end
def
revision
cached_attribute
(
:revision
)
||
read_attribute
(
:revision
)
end
def
architecture
cached_attribute
(
:architecture
)
||
read_attribute
(
:architecture
)
end
def
set_default_values
...
...
@@ -97,7 +105,7 @@ module Ci
end
def
online?
contacted_at
&&
c
ached_c
ontacted_at
>
self
.
class
.
contact_time_deadline
contacted_at
&&
contacted_at
>
self
.
class
.
contact_time_deadline
end
def
status
...
...
@@ -161,16 +169,16 @@ module Ci
ensure_runner_queue_value
==
value
if
value
.
present?
end
def
update_runner_info
(
params
)
update_runner_info_cache
(
params
)
def
update_cached_info
(
values
)
values
=
values
.
slice
(
:version
,
:revision
,
:platform
,
:architecture
)
values
[
:contacted_at
]
=
Time
.
now
# Use a 1h threshold to prevent beating DB updates.
return
unless
self
.
contacted_at
.
nil?
||
(
Time
.
now
-
self
.
contacted_at
)
>=
UPDATE_DB_RUNNER_INFO_EVERY
cache_attributes
(
values
)
self
.
contacted_at
=
Time
.
now
self
.
assign_attributes
(
params
)
self
.
save
if
self
.
changed?
if
persist_cached_data?
self
.
assign_attributes
(
values
)
self
.
save
end
end
private
...
...
@@ -185,24 +193,33 @@ module Ci
"runner:build_queue:
#{
self
.
token
}
"
end
def
runner_info_redis_cache_key
"runner:info:
#{
self
.
id
}
"
def
cache_attribute_key
(
key
)
"runner:info:
#{
self
.
id
}
:
#{
key
}
"
end
def
update_runner_info_cache
(
params
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
redis
.
set
(
"
#{
runner_info_redis_cache_key
}
:contacted_at"
,
Time
.
now
)
def
persist_cached_data?
# Use a random threshold to prevent beating DB updates.
# It generates a distribution between [40m, 80m].
params
&&
params
.
each
do
|
key
,
value
|
redis_key
=
"
#{
runner_info_redis_cache_key
}
:
#{
key
}
"
redis
.
set
(
redis_key
,
value
)
end
contacted_at_max_age
=
UPDATE_DB_RUNNER_INFO_EVERY
+
Random
.
rand
(
UPDATE_DB_RUNNER_INFO_EVERY
)
real_contacted_at
=
read_attribute
(
:contacted_at
)
real_contacted_at
.
nil?
||
(
Time
.
now
-
real_contacted_at
)
>=
contacted_at_max_age
end
def
cached_attribute
(
key
)
@cached_attributes
=
{}
@cached_attributes
[
key
]
||=
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
redis
.
get
(
cache_attribute_key
(
key
))
end
end
def
runner_info_cache
(
attribute
)
def
cache_attributes
(
values
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
redis
.
get
(
"
#{
runner_info_redis_cache_key
}
:
#{
attribute
}
"
)
values
.
each
do
|
key
,
value
|
redis
.
set
(
cache_attribute_key
(
key
),
value
,
ex:
24
.
hours
)
end
end
end
...
...
lib/api/helpers/runner.rb
View file @
38c24212
...
...
@@ -20,7 +20,7 @@ module API
def
authenticate_runner!
forbidden!
unless
current_runner
current_runner
.
update_
runner
_info
(
get_runner_version_from_params
)
current_runner
.
update_
cached
_info
(
get_runner_version_from_params
)
end
def
current_runner
...
...
spec/models/ci/runner_spec.rb
View file @
38c24212
...
...
@@ -146,9 +146,10 @@ describe Ci::Runner do
end
def
stub_redis_runner_contacted_at
(
value
)
redis
=
double
allow
(
Gitlab
::
Redis
::
SharedState
).
to
receive
(
:with
).
and_yield
(
redis
)
allow
(
redis
).
to
receive
(
:get
).
with
(
"
#{
runner
.
send
(
:runner_info_redis_cache_key
)
}
:contacted_at"
).
and_return
(
value
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
cache_key
=
runner
.
send
(
:cache_attribute_key
,
:contacted_at
)
allow
(
redis
).
to
receive
(
:get
).
with
(
cache_key
).
and_return
(
value
)
end
end
end
...
...
@@ -393,10 +394,10 @@ describe Ci::Runner do
end
end
describe
'#update_
runner
_info'
do
describe
'#update_
cached
_info'
do
let
(
:runner
)
{
create
(
:ci_runner
)
}
subject
{
runner
.
update_
runner_info
(
name:
'testing_runner
'
)
}
subject
{
runner
.
update_
cached_info
(
architecture:
'18-bit
'
)
}
context
'when database was updated recently'
do
before
do
...
...
@@ -404,7 +405,7 @@ describe Ci::Runner do
end
it
'updates cache'
do
expect_redis_update
(
:
contacted_at
,
:name
)
expect_redis_update
(
:
architecture
,
:contacted_at
)
subject
end
...
...
@@ -416,26 +417,25 @@ describe Ci::Runner do
end
it
'updates database'
do
expect_redis_update
(
:
contacted_at
,
:name
)
expect_redis_update
(
:
architecture
,
:contacted_at
)
expect
{
subject
}.
to
change
{
runner
.
reload
.
contacted_at
}
.
and
change
{
runner
.
reload
.
name
}
expect
{
subject
}.
to
change
{
runner
.
reload
.
read_attribute
(
:contacted_at
)
}
.
and
change
{
runner
.
reload
.
read_attribute
(
:architecture
)
}
end
it
'updates cache'
do
expect_redis_update
(
:
contacted_at
,
:name
)
expect_redis_update
(
:
architecture
,
:contacted_at
)
subject
end
end
def
expect_redis_update
(
*
params
)
redis
=
double
expect
(
Gitlab
::
Redis
::
SharedState
).
to
receive
(
:with
).
and_yield
(
redis
)
params
.
each
do
|
param
|
redis_key
=
"
#{
runner
.
send
(
:runner_info_redis_cache_key
)
}
:
#{
param
}
"
expect
(
redis
).
to
receive
(
:set
).
with
(
redis_key
,
anything
)
Gitlab
::
Redis
::
SharedState
.
with
do
|
redis
|
params
.
each
do
|
param
|
redis_key
=
runner
.
send
(
:cache_attribute_key
,
param
)
expect
(
redis
).
to
receive
(
:set
).
with
(
redis_key
,
anything
,
any_args
)
end
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