Skip to content

Commit

Permalink
Caching fab task list
Browse files Browse the repository at this point in the history
  • Loading branch information
Jared Proffitt committed Jul 24, 2014
1 parent c730083 commit 7d5bced
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ production.py
scripts
worthwhile_fabfile.py
core.db
.repo_caches
.repo_caches
.django_cache
3 changes: 2 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ v 0.1 (in development)
- Added note in README about creating a super user (thanks madazone!)
- Fixed injection security bug in fab command
- Using virtualenv to run project fabfiles
- Added task argument support!
- Added task argument support!
- Fabric task lists are now cached per project. Invalidate the cache on the project detail page.
8 changes: 8 additions & 0 deletions fabric_bolt/core/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,12 @@
}
########## END LOGGING CONFIGURATION

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(PUBLIC_DIR, '.django_cache'),
}
}


FABRIC_TASK_CACHE_TIMEOUT = 60 * 60 * 24 # one day
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ <h1 style="margin-bottom:30px;" class="col-lg-12">Project {{ object.name }}
</div>
<div>Project Type: {{ object.type }}</div>
<div>Deployments: {{ object.get_deployment_count }}</div>
<div></div>
<div><a href="{% url 'projects_project_invalidate_cache' object.pk %}">Invalidate tasks cache</a></div>
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions fabric_bolt/projects/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
url(r'^view/(?P<pk>\w+)/$', views.ProjectDetail.as_view(), name='projects_project_view'),
url(r'^update/(?P<pk>\w+)/$', views.ProjectUpdate.as_view(), name='projects_project_update'),
url(r'^delete/(?P<pk>\w+)/$', views.ProjectDelete.as_view(), name='projects_project_delete'),
url(r'^invalidate-cache/(?P<pk>\w+)/$', views.ProjectInvalidateCache.as_view(), name='projects_project_invalidate_cache'),

url(r'^(?P<project_id>\w+)/configuration/create/$', views.ProjectConfigurationCreate.as_view(), name='projects_configuration_create'),
url(r'^(?P<project_id>\w+)/configuration/stage/(?P<stage_id>\d+)/create/$', views.ProjectConfigurationCreate.as_view(), name='projects_configuration_stage_create'),
Expand Down
21 changes: 20 additions & 1 deletion fabric_bolt/projects/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.utils.text import slugify
from django.conf import settings
from django.contrib import messages
from django.core.cache import cache

from virtualenv import create_environment

Expand Down Expand Up @@ -52,6 +53,12 @@ def update_project_requirements(project, repo_dir, activate_loc):

def get_fabfile_path(project):
if project.use_repo_fabfile:
cache_key = 'project_{}_fabfile_path'.format(project.pk)
cached_result = cache.get(cache_key)

if cached_result:
return cached_result

cache_dir = os.path.join(settings.PUBLIC_DIR, '.repo_caches')
repo_dir = os.path.join(cache_dir, slugify(project.name))

Expand All @@ -61,7 +68,9 @@ def get_fabfile_path(project):

update_project_requirements(project, repo_dir, activate_loc)

return os.path.join(repo_dir, 'fabfile.py'), activate_loc
result = os.path.join(repo_dir, 'fabfile.py'), activate_loc
cache.set(cache_key, result, settings.FABRIC_TASK_CACHE_TIMEOUT)
return result
else:
return settings.FABFILE_PATH, None

Expand All @@ -70,6 +79,13 @@ def get_fabric_tasks(request, project):
"""
Generate a list of fabric tasks that are available
"""

cache_key = 'project_{}_fabfile_tasks'.format(project.pk)
cached_result = cache.get(cache_key)

if cached_result:
return cached_result

try:
fabfile_path, activate_loc = get_fabfile_path(project)

Expand Down Expand Up @@ -99,9 +115,12 @@ def get_fabric_tasks(request, project):
except:
pass # just stick with the original truncated description
dict_with_docs[name] = desc

cache.set(cache_key, dict_with_docs, settings.FABRIC_TASK_CACHE_TIMEOUT)
except Exception as e:
messages.error(request, 'Error loading fabfile: ' + str(e))
dict_with_docs = {}

return dict_with_docs


Expand Down
18 changes: 18 additions & 0 deletions fabric_bolt/projects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.shortcuts import get_object_or_404
from django.forms import CharField, PasswordInput, Select, FloatField, BooleanField
from django.conf import settings
from django.core.cache import cache

from django_tables2 import RequestConfig, SingleTableView

Expand Down Expand Up @@ -483,3 +484,20 @@ def get(self, request, *args, **kwargs):

def get_redirect_url(self, **kwargs):
return reverse('projects_stage_view', args=(self.stage.project.pk, self.stage_id,))


class ProjectInvalidateCache(RedirectView):
permanent = False

def get(self, request, *args, **kwargs):
self.project_id = kwargs.get('pk')

cache.delete_many(['project_{}_fabfile_tasks'.format(self.project_id),
'project_{}_fabfile_path'.format(self.project_id)])

messages.info(request, "Tasks cache invalidated.")

return super(ProjectInvalidateCache, self).get(request, *args, **kwargs)

def get_redirect_url(self, **kwargs):
return reverse('projects_project_view', args=(self.project_id,))

0 comments on commit 7d5bced

Please sign in to comment.