diff options
author | 2019-09-15 23:49:56 +0200 | |
---|---|---|
committer | 2019-09-15 23:49:56 +0200 | |
commit | a02e8b7610589838e69190c94f2821bda2f73cba (patch) | |
tree | 0f8c7bfa4c8ae5826b4f006f7c11f359c0cd8770 | |
parent | PARENT_HOST is now pythondiscord.com (diff) |
Fix a bug where GitHub API rate limit could crash Home.
The bug was caused by a naive approach to caching and retrieving the data.
This commit rectifies this by making the following changes:
- We will now cache for 1 hour instead of 10 minutes
- If the data is stale but API is rate limited, return cache, not crash.
- If the cache doesn't exist and API is rate limited, return dummy data,
and try again in 10 minutes.
This will prevent all crashes, and should still have more or less the same user experience.
-rw-r--r-- | pydis_site/apps/home/views/home.py | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py index 63f25c15..4cf22594 100644 --- a/pydis_site/apps/home/views/home.py +++ b/pydis_site/apps/home/views/home.py @@ -1,3 +1,4 @@ +import datetime from typing import Dict, List import requests @@ -14,7 +15,7 @@ class HomeView(View): """The main landing page for the website.""" github_api = "https://api.github.com/users/python-discord/repos" - repository_cache_ttl = 600 + repository_cache_ttl = 3600 # Which of our GitHub repos should be displayed on the front page, and in which order? repos = [ @@ -45,6 +46,7 @@ class HomeView(View): "forks_count": repo["forks_count"], "stargazers_count": repo["stargazers_count"], } + return repo_dict def _get_repo_data(self) -> List[RepositoryMetadata]: @@ -56,8 +58,11 @@ class HomeView(View): # If the data is stale, we should refresh it. if (timezone.now() - repo_data.last_updated).seconds > self.repository_cache_ttl: - # Get new data from API - api_repositories = self._get_api_data() + # Try to get new data from the API. If it fails, return the cached data. + try: + api_repositories = self._get_api_data() + except TypeError: + return RepositoryMetadata.objects.all() database_repositories = [] # Update or create all RepoData objects in self.repos @@ -86,22 +91,34 @@ class HomeView(View): # If this is raised, the database has no repodata at all, we will create them all. except RepositoryMetadata.DoesNotExist: - - # Get new data from API - api_repositories = self._get_api_data() database_repositories = [] + try: + # Get new data from API + api_repositories = self._get_api_data() - # Create all the repodata records in the database. - for api_data in api_repositories.values(): - repo_data = RepositoryMetadata( - repo_name=api_data["full_name"], - description=api_data["description"], - forks=api_data["forks_count"], - stargazers=api_data["stargazers_count"], - language=api_data["language"], - ) - repo_data.save() - database_repositories.append(repo_data) + # Create all the repodata records in the database. + for api_data in api_repositories.values(): + repo_data = RepositoryMetadata( + repo_name=api_data["full_name"], + description=api_data["description"], + forks=api_data["forks_count"], + stargazers=api_data["stargazers_count"], + language=api_data["language"], + ) + repo_data.save() + database_repositories.append(repo_data) + except TypeError: + for repo_name in self.repos: + repo_data = RepositoryMetadata( + last_updated=timezone.now() - datetime.timedelta(minutes=50), + repo_name=repo_name, + description="Not available.", + forks=999, + stargazers=999, + language="Python", + ) + repo_data.save() + database_repositories.append(repo_data) return database_repositories |