From 389a2a4a4d24e99d71f7f39bf39e988dd3790899 Mon Sep 17 00:00:00 2001 From: Emilien Devos Date: Sat, 10 Jun 2023 22:21:38 +0200 Subject: [PATCH] use redis for video cache Signed-off-by: zzls Selfhost --- shard.lock | 8 ++++++++ shard.yml | 2 ++ src/invidious.cr | 8 +++++++- src/invidious/config.cr | 2 ++ src/invidious/database/videos.cr | 16 +++++++++++++--- src/invidious/videos.cr | 2 +- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/shard.lock b/shard.lock index 397bd8bc..8c599d1b 100644 --- a/shard.lock +++ b/shard.lock @@ -32,6 +32,10 @@ shards: git: https://github.com/will/crystal-pg.git version: 0.24.0 + pool: + git: https://github.com/ysbaddaden/pool.git + version: 0.2.4 + protodec: git: https://github.com/iv-org/protodec.git version: 0.1.5 @@ -40,6 +44,10 @@ shards: git: https://github.com/luislavena/radix.git version: 0.4.1 + redis: + git: https://github.com/stefanwille/crystal-redis.git + version: 2.9.1 + spectator: git: https://github.com/icy-arctic-fox/spectator.git version: 0.10.4 diff --git a/shard.yml b/shard.yml index 367f7c73..c46e1c42 100644 --- a/shard.yml +++ b/shard.yml @@ -28,6 +28,8 @@ dependencies: athena-negotiation: github: athena-framework/negotiation version: ~> 0.1.1 + redis: + github: stefanwille/crystal-redis development_dependencies: spectator: diff --git a/src/invidious.cr b/src/invidious.cr index 64578061..218c1c9f 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -31,6 +31,7 @@ require "xml" require "yaml" require "compress/zip" require "protodec/utils" +require "redis" require "./invidious/database/*" require "./invidious/database/migrations/*" @@ -60,7 +61,12 @@ alias IV = Invidious CONFIG = Config.load HMAC_KEY = CONFIG.hmac_key -PG_DB = DB.open CONFIG.database_url +PG_DB = DB.open CONFIG.database_url +REDIS_DB = Redis::PooledClient.new(unixsocket: CONFIG.redis_socket || nil, url: CONFIG.redis_url || nil) + +if REDIS_DB.ping + puts "Connected to redis" +end ARCHIVE_URL = URI.parse("https://archive.org") PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com") REDDIT_URL = URI.parse("https://www.reddit.com") diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 50677546..053e76bf 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -74,6 +74,8 @@ class Config # Database configuration using 12-Factor "Database URL" syntax @[YAML::Field(converter: Preferences::URIConverter)] property database_url : URI = URI.parse("") + property redis_url : String? + property redis_socket : String? # Use polling to keep decryption function up to date property decrypt_polling : Bool = false # Used for crawling channels: threads should check all videos uploaded by a channel diff --git a/src/invidious/database/videos.cr b/src/invidious/database/videos.cr index 695f5b33..776ef5b1 100644 --- a/src/invidious/database/videos.cr +++ b/src/invidious/database/videos.cr @@ -10,7 +10,8 @@ module Invidious::Database::Videos ON CONFLICT (id) DO NOTHING SQL - PG_DB.exec(request, video.id, video.info.to_json, video.updated) + REDIS_DB.set(video.id, video.info.to_json, ex: 3600) + REDIS_DB.set(video.id + ":time", video.updated, ex: 3600) end def delete(id) @@ -19,7 +20,8 @@ module Invidious::Database::Videos WHERE id = $1 SQL - PG_DB.exec(request, id) + REDIS_DB.del(id) + REDIS_DB.del(id + ":time") end def delete_expired @@ -47,6 +49,14 @@ module Invidious::Database::Videos WHERE id = $1 SQL - return PG_DB.query_one?(request, id, as: Video) + if ((info = REDIS_DB.get(id)) && (time = REDIS_DB.get(id + ":time"))) + return Video.new({ + id: id, + info: JSON.parse(info).as_h, + updated: Time.parse(time, "%Y-%m-%d %H:%M:%S %z", Time::Location::UTC), + }) + else + return nil + end end end diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index cdfca02c..2b1ccff8 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -373,7 +373,7 @@ def get_video(id, refresh = true, region = nil, force_refresh = false) video.schema_version != Video::SCHEMA_VERSION # cache control begin video = fetch_video(id, region) - Invidious::Database::Videos.update(video) + Invidious::Database::Videos.insert(video) rescue ex Invidious::Database::Videos.delete(id) raise ex