-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
move commit fetching to celery task #5275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,6 @@ | |
|
|
||
| import logging | ||
| import re | ||
| import six | ||
|
|
||
| from django.db import models, IntegrityError, transaction | ||
| from django.db.models import F | ||
|
|
@@ -19,7 +18,6 @@ | |
| from sentry.db.models import ( | ||
| BoundedPositiveIntegerField, FlexibleForeignKey, Model, sane_repr | ||
| ) | ||
| from sentry.exceptions import InvalidIdentity, PluginError | ||
| from sentry.utils.cache import cache | ||
| from sentry.utils.hashlib import md5_text | ||
|
|
||
|
|
@@ -247,9 +245,9 @@ def add_project(self, project): | |
| else: | ||
| return True | ||
|
|
||
| def set_refs(self, refs, user, fetch_commits=False): | ||
| def set_refs(self, refs, user, fetch=False): | ||
| from sentry.models import Commit, ReleaseHeadCommit, Repository | ||
| from sentry.plugins import bindings | ||
| from sentry.tasks.commits import fetch_commits | ||
|
|
||
| # TODO: this does the wrong thing unless you are on the most | ||
| # recent release. Add a timestamp compare? | ||
|
|
@@ -258,8 +256,6 @@ def set_refs(self, refs, user, fetch_commits=False): | |
| projects__in=self.projects.all(), | ||
| ).exclude(version=self.version).order_by('-date_added').first() | ||
|
|
||
| commit_list = [] | ||
|
|
||
| for ref in refs: | ||
| try: | ||
| repo = Repository.objects.get( | ||
|
|
@@ -283,43 +279,15 @@ def set_refs(self, refs, user, fetch_commits=False): | |
| 'commit': commit, | ||
| } | ||
| ) | ||
| if fetch_commits: | ||
| try: | ||
| provider_cls = bindings.get('repository.provider').get(repo.provider) | ||
| except KeyError: | ||
| continue | ||
|
|
||
| # if previous commit isn't provided, try to get from | ||
| # previous release otherwise, give up | ||
| if ref.get('previousCommit'): | ||
| start_sha = ref['previousCommit'] | ||
| elif prev_release: | ||
| try: | ||
| start_sha = Commit.objects.filter( | ||
| organization_id=self.organization_id, | ||
| releaseheadcommit__release=prev_release, | ||
| repository_id=repo.id, | ||
| ).values_list('key', flat=True)[0] | ||
| except IndexError: | ||
| continue | ||
| else: | ||
| continue | ||
|
|
||
| end_sha = commit.key | ||
| provider = provider_cls(id=repo.provider) | ||
| try: | ||
| repo_commits = provider.compare_commits( | ||
| repo, start_sha, end_sha, actor=user | ||
| ) | ||
| except NotImplementedError: | ||
| pass | ||
| except (PluginError, InvalidIdentity) as e: | ||
| logger.exception(six.text_type(e)) | ||
| else: | ||
| commit_list.extend(repo_commits) | ||
|
|
||
| if commit_list: | ||
| self.set_commits(commit_list) | ||
| if fetch: | ||
| fetch_commits.apply_async( | ||
| kwargs={ | ||
| 'release_id': self.id, | ||
| 'user_id': user.id, | ||
| 'refs': refs, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How large are these If not, we're good. Otherwise, I'd want to slim this down before throwing into the queue.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🌮 |
||
| 'prev_release_id': prev_release and prev_release.id, | ||
| } | ||
| ) | ||
|
|
||
| def set_commits(self, commit_list): | ||
| from sentry.models import ( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| from __future__ import absolute_import | ||
|
|
||
| import logging | ||
| import six | ||
|
|
||
| from sentry.exceptions import InvalidIdentity, PluginError | ||
| from sentry.models import Commit, Release, Repository, User | ||
| from sentry.plugins import bindings | ||
| from sentry.tasks.base import instrumented_task, retry | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| @instrumented_task(name='sentry.tasks.commit.fetch_commits', queue='commits', | ||
| default_retry_delay=60 * 5, max_retries=5) | ||
| @retry(exclude=(Release.DoesNotExist, User.DoesNotExist,)) | ||
| def fetch_commits(release_id, user_id, refs, prev_release_id=None, **kwargs): | ||
| commit_list = [] | ||
|
|
||
| release = Release.objects.get(id=release_id) | ||
| user = User.objects.get(id=user_id) | ||
|
|
||
| prev_release = None | ||
| if prev_release_id is not None: | ||
| try: | ||
| prev_release = Release.objects.get(id=prev_release_id) | ||
| except Release.DoesNotExist: | ||
| pass | ||
|
|
||
| for ref in refs: | ||
| try: | ||
| repo = Repository.objects.get( | ||
| organization_id=release.organization_id, | ||
| name=ref['repository'], | ||
| ) | ||
| except Repository.DoesNotExist: | ||
| continue | ||
|
|
||
| try: | ||
| commit = Commit.objects.get( | ||
| organization_id=release.organization_id, | ||
| repository_id=repo.id, | ||
| key=ref['commit'], | ||
| ) | ||
| except Commit.DoesNotExist: | ||
| continue | ||
|
|
||
| try: | ||
| provider_cls = bindings.get('repository.provider').get(repo.provider) | ||
| except KeyError: | ||
| continue | ||
|
|
||
| # if previous commit isn't provided, try to get from | ||
| # previous release otherwise, give up | ||
| if ref.get('previousCommit'): | ||
| start_sha = ref['previousCommit'] | ||
| elif prev_release: | ||
| try: | ||
| start_sha = Commit.objects.filter( | ||
| organization_id=release.organization_id, | ||
| releaseheadcommit__release=prev_release, | ||
| repository_id=repo.id, | ||
| ).values_list('key', flat=True)[0] | ||
| except IndexError: | ||
| continue | ||
| else: | ||
| continue | ||
|
|
||
| end_sha = commit.key | ||
| provider = provider_cls(id=repo.provider) | ||
| try: | ||
| repo_commits = provider.compare_commits( | ||
| repo, start_sha, end_sha, actor=user | ||
| ) | ||
| except NotImplementedError: | ||
| pass | ||
| except (PluginError, InvalidIdentity) as e: | ||
| logger.exception(six.text_type(e)) | ||
| else: | ||
| commit_list.extend(repo_commits) | ||
|
|
||
| if commit_list: | ||
| release.set_commits(commit_list) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JTCunning these is going to get picked up by a
worker-globworker, right?We also might need to explicitly add the queue to federation. I don't fully remember how that works. (Should prob document)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will get picked up there, and I'm not completely sure we need to add it to the federation list unless we expect this to be heavily populated.
https://github.com/getsentry/ops/blob/master/cookbooks/getsentry/recipes/queue.rb#L86