Helper for cache related utilities (#6696)

Co-authored-by: Tom Moor <tom@getoutline.com>
This commit is contained in:
Apoorv Mishra
2024-03-22 05:19:38 +05:30
committed by GitHub
parent 3b7010337c
commit bd2b32f9d5
5 changed files with 97 additions and 60 deletions

View File

@@ -1,57 +1,22 @@
import type { Unfurl } from "@shared/types";
import { Day } from "@shared/utils/time";
import { InternalError } from "@server/errors";
import Logger from "@server/logging/Logger";
import Redis from "@server/storage/redis";
import fetch from "@server/utils/fetch";
import env from "./env";
class Iframely {
private static apiUrl = `${env.IFRAMELY_URL}/api`;
private static apiKey = env.IFRAMELY_API_KEY;
private static cacheKeyPrefix = "unfurl";
private static defaultCacheExpiry = Day;
private static cacheKey(url: string) {
return `${this.cacheKeyPrefix}-${url}`;
}
private static async cache(url: string, response: any) {
// do not cache error responses
if (response.error) {
return;
}
try {
await Redis.defaultClient.set(
this.cacheKey(url),
JSON.stringify(response),
"EX",
response.cache_age || this.defaultCacheExpiry
);
} catch (err) {
// just log it, can skip caching and directly return response
Logger.error("Could not cache Iframely response", err);
}
}
public static async fetch(url: string, type = "oembed") {
const res = await fetch(
`${this.apiUrl}/${type}?url=${encodeURIComponent(url)}&api_key=${
this.apiKey
}`
);
return res.json();
}
private static async cached(url: string) {
try {
const val = await Redis.defaultClient.get(this.cacheKey(url));
if (val) {
return JSON.parse(val);
}
const res = await fetch(
`${this.apiUrl}/${type}?url=${encodeURIComponent(url)}&api_key=${
this.apiKey
}`
);
return res.json();
} catch (err) {
// just log it, response can still be obtained using the fetch call
Logger.error("Could not fetch cached Iframely response", err);
throw InternalError(err);
}
}
@@ -61,18 +26,8 @@ class Iframely {
* @param url
* @returns Preview data for the url
*/
public static async get(url: string): Promise<Unfurl | false> {
try {
const cached = await Iframely.cached(url);
if (cached) {
return cached;
}
const res = await Iframely.fetch(url);
await Iframely.cache(url, res);
return res;
} catch (err) {
throw InternalError(err);
}
public static async unfurl(url: string): Promise<Unfurl | false> {
return Iframely.fetch(url);
}
}

View File

@@ -1,3 +1,4 @@
import { Day } from "@shared/utils/time";
import {
PluginManager,
PluginPriority,
@@ -12,7 +13,7 @@ if (enabled) {
PluginManager.add([
{
type: Hook.UnfurlProvider,
value: Iframely.get,
value: { unfurl: Iframely.unfurl, cacheExpiry: Day },
// Make sure this is last in the stack to be evaluated after all other unfurl providers
priority: PluginPriority.VeryLow,