Skip to content

Commit 8fa3eb2

Browse files
authored
Merge pull request #715 from furlongm/redis-caching
use redis for caching and use locks for tasks
2 parents 60a80cd + 00fbd6e commit 8fa3eb2

File tree

5 files changed

+101
-48
lines changed

5 files changed

+101
-48
lines changed

errata/tasks.py

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616

1717
from celery import shared_task
1818

19+
from django.core.cache import cache
20+
1921
from errata.sources.distros.arch import update_arch_errata
2022
from errata.sources.distros.alma import update_alma_errata
2123
from errata.sources.distros.debian import update_debian_errata
2224
from errata.sources.distros.centos import update_centos_errata
2325
from errata.sources.distros.rocky import update_rocky_errata
2426
from errata.sources.distros.ubuntu import update_ubuntu_errata
25-
from util.logging import error_message
27+
from util.logging import error_message, warning_message
2628
from repos.models import Repository
2729
from security.tasks import update_cves, update_cwes
2830
from util import get_setting_of_type
@@ -44,34 +46,44 @@ def update_yum_repo_errata(repo_id=None, force=False):
4446
def update_errata(erratum_type=None, force=False, repo=None):
4547
""" Update all distros errata
4648
"""
47-
errata_os_updates = []
48-
erratum_types = ['yum', 'rocky', 'alma', 'arch', 'ubuntu', 'debian', 'centos']
49-
erratum_type_defaults = ['yum', 'rocky', 'alma', 'arch', 'ubuntu', 'debian']
50-
if erratum_type:
51-
if erratum_type not in erratum_types:
52-
error_message.send(sender=None, text=f'Erratum type `{erratum_type}` not in {erratum_types}')
53-
else:
54-
errata_os_updates = erratum_type
49+
lock_key = 'update_errata_lock'
50+
# lock will expire after 48 hours
51+
lock_expire = 60 * 60 * 48
52+
53+
if cache.add(lock_key, 'true', lock_expire):
54+
try:
55+
errata_os_updates = []
56+
erratum_types = ['yum', 'rocky', 'alma', 'arch', 'ubuntu', 'debian', 'centos']
57+
erratum_type_defaults = ['yum', 'rocky', 'alma', 'arch', 'ubuntu', 'debian']
58+
if erratum_type:
59+
if erratum_type not in erratum_types:
60+
error_message(text=f'Erratum type `{erratum_type}` not in {erratum_types}')
61+
else:
62+
errata_os_updates = erratum_type
63+
else:
64+
errata_os_updates = get_setting_of_type(
65+
setting_name='ERRATA_OS_UPDATES',
66+
setting_type=list,
67+
default=erratum_type_defaults,
68+
)
69+
if 'yum' in errata_os_updates:
70+
update_yum_repo_errata(repo_id=repo, force=force)
71+
if 'arch' in errata_os_updates:
72+
update_arch_errata()
73+
if 'alma' in errata_os_updates:
74+
update_alma_errata()
75+
if 'rocky' in errata_os_updates:
76+
update_rocky_errata()
77+
if 'debian' in errata_os_updates:
78+
update_debian_errata()
79+
if 'ubuntu' in errata_os_updates:
80+
update_ubuntu_errata()
81+
if 'centos' in errata_os_updates:
82+
update_centos_errata()
83+
finally:
84+
cache.delete(lock_key)
5585
else:
56-
errata_os_updates = get_setting_of_type(
57-
setting_name='ERRATA_OS_UPDATES',
58-
setting_type=list,
59-
default=erratum_type_defaults,
60-
)
61-
if 'yum' in errata_os_updates:
62-
update_yum_repo_errata(repo_id=repo, force=force)
63-
if 'arch' in errata_os_updates:
64-
update_arch_errata()
65-
if 'alma' in errata_os_updates:
66-
update_alma_errata()
67-
if 'rocky' in errata_os_updates:
68-
update_rocky_errata()
69-
if 'debian' in errata_os_updates:
70-
update_debian_errata()
71-
if 'ubuntu' in errata_os_updates:
72-
update_ubuntu_errata()
73-
if 'centos' in errata_os_updates:
74-
update_centos_errata()
86+
warning_message('Already updating Errata, skipping task.')
7587

7688

7789
@shared_task

etc/patchman/local_settings.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,16 @@
5656
# Whether to run patchman under the gunicorn web server
5757
RUN_GUNICORN = False
5858

59+
# Set the default timeout to e.g. 30 seconds to enable UI caching
60+
# Note that the UI results may be out of date for this amount of time
5961
CACHES = {
6062
'default': {
61-
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
63+
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
64+
'LOCATION': 'redis://127.0.0.1:6379',
65+
'TIMEOUT': 0,
6266
}
6367
}
6468

65-
# Uncomment to enable redis caching for e.g. 30 seconds
66-
# Note that the UI results may be out of date for this amount of time
67-
# CACHES = {
68-
# 'default': {
69-
# 'BACKEND': 'django.core.cache.backends.redis.RedisCache',
70-
# 'LOCATION': 'redis://127.0.0.1:6379',
71-
# 'TIMEOUT': 30,
72-
# }
73-
# }
74-
7569
from datetime import timedelta # noqa
7670
from celery.schedules import crontab # noqa
7771
CELERY_BEAT_SCHEDULE = {

reports/tasks.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,30 @@
1717

1818
from celery import shared_task
1919

20+
from django.core.cache import cache
2021
from django.db.utils import OperationalError
2122

2223
from hosts.models import Host
2324
from reports.models import Report
24-
from util.logging import info_message
25+
from util.logging import info_message, warning_message
2526

2627

2728
@shared_task(bind=True, autoretry_for=(OperationalError,), retry_backoff=True, retry_kwargs={'max_retries': 5})
2829
def process_report(self, report_id):
2930
""" Task to process a single report
3031
"""
3132
report = Report.objects.get(id=report_id)
32-
report.process()
33+
lock_key = f'process_report_lock_{report_id}'
34+
# lock will expire after 1 hour
35+
lock_expire = 60 * 60
36+
37+
if cache.add(lock_key, 'true', lock_expire):
38+
try:
39+
report.process()
40+
finally:
41+
cache.delete(lock_key)
42+
else:
43+
warning_message(f'Already processing report {report_id}, skipping task.')
3344

3445

3546
@shared_task

repos/tasks.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
from celery import shared_task
1818

19+
from django.core.cache import cache
20+
1921
from repos.models import Repository
22+
from util.logging import warning_message
2023

2124

2225
@shared_task
@@ -32,5 +35,15 @@ def refresh_repos(force=False):
3235
""" Refresh metadata for all enabled repos
3336
"""
3437
repos = Repository.objects.filter(enabled=True)
35-
for repo in repos:
36-
refresh_repo.delay(repo.id, force)
38+
lock_key = 'refresh_repos_lock'
39+
# lock will expire after 1 day
40+
lock_expire = 60 * 60 * 24
41+
42+
if cache.add(lock_key, 'true', lock_expire):
43+
try:
44+
for repo in repos:
45+
refresh_repo.delay(repo.id, force)
46+
finally:
47+
cache.delete(lock_key)
48+
else:
49+
warning_message('Already refreshing repos, skipping task.')

security/tasks.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
from celery import shared_task
1818

19+
from django.core.cache import cache
20+
1921
from security.models import CVE, CWE
22+
from util.logging import warning_message
2023

2124

2225
@shared_task
@@ -31,8 +34,18 @@ def update_cve(cve_id):
3134
def update_cves():
3235
""" Task to update all CVEs
3336
"""
34-
for cve in CVE.objects.all():
35-
update_cve.delay(cve.id)
37+
lock_key = 'update_cves_lock'
38+
# lock will expire after 1 week
39+
lock_expire = 60 * 60 * 168
40+
41+
if cache.add(lock_key, 'true', lock_expire):
42+
try:
43+
for cve in CVE.objects.all():
44+
update_cve.delay(cve.id)
45+
finally:
46+
cache.delete(lock_key)
47+
else:
48+
warning_message('Already updating CVEs, skipping task.')
3649

3750

3851
@shared_task
@@ -45,7 +58,17 @@ def update_cwe(cwe_id):
4558

4659
@shared_task
4760
def update_cwes():
48-
""" Task to update all CWEa
61+
""" Task to update all CWEs
4962
"""
50-
for cwe in CWE.objects.all():
51-
update_cwe.delay(cwe.id)
63+
lock_key = 'update_cwes_lock'
64+
# lock will expire after 1 week
65+
lock_expire = 60 * 60 * 168
66+
67+
if cache.add(lock_key, 'true', lock_expire):
68+
try:
69+
for cwe in CWE.objects.all():
70+
update_cwe.delay(cwe.id)
71+
finally:
72+
cache.delete(lock_key)
73+
else:
74+
warning_message('Already updating CWEs, skipping task.')

0 commit comments

Comments
 (0)