aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-03-24 00:06:59 -0700
committerFuwn <[email protected]>2022-03-24 00:06:59 -0700
commit0ae95f06ed05a774137aab654857e3e26614c16e (patch)
treed06942db46df80474b77de6bfc993cd99d6af1bf
parentfeat(api): /me route (diff)
downloadapi-worker-0ae95f06ed05a774137aab654857e3e26614c16e.tar.xz
api-worker-0ae95f06ed05a774137aab654857e3e26614c16e.zip
feat: cache github api
This commit allows The Senpy Club API to cache GitHub's API response, refreshing the cache every fifty accesses. This commit also gets rid of a few dependencies which were replaced by their standard library counterparts.
-rw-r--r--Cargo.toml7
-rw-r--r--src/constants.rs44
-rw-r--r--src/lib.rs1
-rw-r--r--src/structures.rs4
-rw-r--r--src/utils.rs58
5 files changed, 64 insertions, 50 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 4c71625..8caad89 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,7 @@
[package]
name = "api-worker"
-version = "0.1.0"
+version = "0.2.0"
authors = ["Fuwn <[email protected]>"]
edition = "2021"
description = "API (as a Cloudflare Worker!)"
@@ -38,11 +38,6 @@ dotenv = "0.15.0"
# Worker
worker = "0.0.9"
-# Utility
-cfg-if = "1.0.0"
-const_format = "0.2.22"
-lazy_static = "1.4.0"
-
# Web
reqwest = { version = "0.11.10", features = ["json"] }
diff --git a/src/constants.rs b/src/constants.rs
index 6f3e6e4..ad46dfd 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -16,27 +16,29 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
-use const_format::formatcp;
-
-lazy_static::lazy_static! {
- pub static ref INDEX: String = {
- format!(
- include_str!("index.rst"),
- format_args!(
- "https://github.com/senpy-club/api-worker/tree/{}",
- env!("VERGEN_GIT_SHA"),
- )
- )
- };
-}
+use std::lazy::SyncLazy;
const GITHUB_REPOSITORY: &str =
"cat-milk/Anime-Girls-Holding-Programming-Books";
-pub const GITHUB_USER_CONTENT: &str = formatcp!(
- "https://raw.githubusercontent.com/{}/master/",
- GITHUB_REPOSITORY
-);
-pub const GITHUB_API_ENDPOINT: &str = formatcp!(
- "https://api.github.com/repos/{}/git/trees/master?recursive=1",
- GITHUB_REPOSITORY,
-);
+
+pub static INDEX: SyncLazy<String> = SyncLazy::new(|| {
+ format!(
+ include_str!("index.rst"),
+ format_args!(
+ "https://github.com/senpy-club/api-worker/tree/{}",
+ env!("VERGEN_GIT_SHA"),
+ )
+ )
+});
+pub static GITHUB_USER_CONTENT: SyncLazy<String> = SyncLazy::new(|| {
+ format!(
+ "https://raw.githubusercontent.com/{}/master/",
+ GITHUB_REPOSITORY
+ )
+});
+pub static GITHUB_API_ENDPOINT: SyncLazy<String> = SyncLazy::new(|| {
+ format!(
+ "https://api.github.com/repos/{}/git/trees/master?recursive=1",
+ GITHUB_REPOSITORY,
+ )
+});
diff --git a/src/lib.rs b/src/lib.rs
index 2287e89..507c927 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -16,6 +16,7 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
+#![feature(once_cell)]
#![deny(
warnings,
nonstandard_style,
diff --git a/src/structures.rs b/src/structures.rs
index 3e9b7bc..4c59d51 100644
--- a/src/structures.rs
+++ b/src/structures.rs
@@ -20,7 +20,7 @@
use serde_derive::{Deserialize, Serialize};
-#[derive(Serialize, Deserialize)]
+#[derive(Serialize, Deserialize, Clone)]
pub struct GitHubAPIResponse {
pub sha: String,
pub url: String,
@@ -38,7 +38,7 @@ impl Default for GitHubAPIResponse {
}
}
-#[derive(Serialize, Deserialize, Default)]
+#[derive(Serialize, Deserialize, Default, Clone)]
pub struct GitHubAPIResponseTree {
pub path: String,
pub mode: String,
diff --git a/src/utils.rs b/src/utils.rs
index 8bb70da..333a1c0 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -16,39 +16,55 @@
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only
+use std::{lazy::SyncLazy, sync::Mutex};
+
use worker::Cors;
use crate::{constants, structures::GitHubAPIResponse};
+static CACHE_UNSET: SyncLazy<Mutex<bool>> = SyncLazy::new(|| Mutex::new(true));
+static CACHE_ACCESS_COUNT: SyncLazy<Mutex<usize>> =
+ SyncLazy::new(|| Mutex::new(0));
+static GITHUB_API_CACHE: SyncLazy<Mutex<GitHubAPIResponse>> =
+ SyncLazy::new(|| Mutex::new(GitHubAPIResponse::default()));
+
/// # Errors
/// if GitHub API is unresponsive
pub async fn github_api(
) -> Result<GitHubAPIResponse, Box<dyn std::error::Error>> {
- let mut client = reqwest::Client::new()
- .get(constants::GITHUB_API_ENDPOINT)
- .header(
- "User-Agent",
- format!("senpy-club/api-worker - {}", env!("VERGEN_GIT_SHA")),
- );
-
- if std::env::var("GITHUB_TOKEN").is_ok() {
- client = client.header(
- "Authorization",
- format!(
- "token {}",
- std::env::var("GITHUB_TOKEN").unwrap_or_else(|_| "Null".to_string())
- ),
- );
- }
+ if *CACHE_UNSET.lock().unwrap()
+ || *CACHE_ACCESS_COUNT.lock().unwrap() % 50 == 0
+ {
+ *CACHE_UNSET.lock().unwrap() = false;
- Ok(
- client
+ let mut client = reqwest::Client::new()
+ .get(&*constants::GITHUB_API_ENDPOINT)
+ .header(
+ "User-Agent",
+ format!("senpy-club/api-worker - {}", env!("VERGEN_GIT_SHA")),
+ );
+
+ if std::env::var("GITHUB_TOKEN").is_ok() {
+ client = client.header(
+ "Authorization",
+ format!(
+ "token {}",
+ std::env::var("GITHUB_TOKEN").unwrap_or_else(|_| "Null".to_string())
+ ),
+ );
+ }
+
+ *GITHUB_API_CACHE.lock().unwrap() = client
.send()
.await?
.json::<GitHubAPIResponse>()
.await
- .unwrap_or_default(),
- )
+ .unwrap_or_default();
+ }
+
+ *CACHE_ACCESS_COUNT.lock().unwrap() += 1;
+
+ Ok((*GITHUB_API_CACHE.lock().unwrap()).clone())
}
/// # Panics
@@ -79,7 +95,7 @@ pub async fn filter_images_by_language(language: &str) -> Vec<String> {
{
images.push(format!(
"{}{}",
- constants::GITHUB_USER_CONTENT,
+ *constants::GITHUB_USER_CONTENT,
// Pound symbols to URL (percent) encoding of pound symbol because we
// are pushing a URL, not a string
item.path.replace('#', "%23")