feat(database): support for either Redis or PostgreSQL for video cache
All checks were successful
Invidious CI / build (push) Successful in 5m33s
All checks were successful
Invidious CI / build (push) Successful in 5m33s
This commit is contained in:
parent
1df1945849
commit
bbc5913b8d
2 changed files with 73 additions and 18 deletions
|
@ -76,12 +76,8 @@ end
|
||||||
|
|
||||||
HMAC_KEY = CONFIG.hmac_key
|
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")
|
ARCHIVE_URL = URI.parse("https://archive.org")
|
||||||
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
|
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
|
||||||
REDDIT_URL = URI.parse("https://www.reddit.com")
|
REDDIT_URL = URI.parse("https://www.reddit.com")
|
||||||
|
@ -156,6 +152,19 @@ end
|
||||||
OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a")
|
OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a")
|
||||||
LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level, CONFIG.colorize_logs)
|
LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level, CONFIG.colorize_logs)
|
||||||
|
|
||||||
|
REDIS_DB = begin
|
||||||
|
LOGGER.info "Connecting to Redis compatible DB"
|
||||||
|
redis = Redis::PooledClient.new(unixsocket: CONFIG.redis_socket || nil, url: CONFIG.redis_url || nil)
|
||||||
|
if redis.ping
|
||||||
|
LOGGER.info "Connected to Redis compatible DB via unix domain socket at '#{CONFIG.redis_socket}'" if CONFIG.redis_socket
|
||||||
|
LOGGER.info "Connected to Redis compatible DB via TCP socket at '#{CONFIG.redis_url}'" if CONFIG.redis_url
|
||||||
|
end
|
||||||
|
redis
|
||||||
|
rescue ex
|
||||||
|
LOGGER.error "Failed to connect to a Redis compatible DB. Invidious will store the video cache on the PostgresSQL DB"
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
# Check table integrity
|
# Check table integrity
|
||||||
Invidious::Database.check_integrity(CONFIG)
|
Invidious::Database.check_integrity(CONFIG)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,70 @@
|
||||||
require "./base.cr"
|
require "./base.cr"
|
||||||
|
|
||||||
module Invidious::Database::Videos
|
module Invidious::Database::Videos
|
||||||
|
module DBCache
|
||||||
|
extend self
|
||||||
|
|
||||||
|
def set(video : Video, expire_time)
|
||||||
|
if redis = REDIS_DB
|
||||||
|
redis.set(video.id, video.info.to_json, expire_time)
|
||||||
|
redis.set(video.id + ":time", video.updated, expire_time)
|
||||||
|
else
|
||||||
|
request = <<-SQL
|
||||||
|
INSERT INTO videos
|
||||||
|
VALUES ($1, $2, $3)
|
||||||
|
ON CONFLICT (id) DO NOTHING
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, video.id, video.info.to_json, video.updated)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def del(id : String)
|
||||||
|
if redis = REDIS_DB
|
||||||
|
redis.del(id)
|
||||||
|
redis.del(id + ":time")
|
||||||
|
else
|
||||||
|
request = <<-SQL
|
||||||
|
DELETE FROM videos *
|
||||||
|
WHERE id = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
PG_DB.exec(request, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(id : String)
|
||||||
|
if redis = REDIS_DB
|
||||||
|
info = redis.get(id)
|
||||||
|
time = redis.get(id + ":time")
|
||||||
|
if info && 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
|
||||||
|
else
|
||||||
|
request = <<-SQL
|
||||||
|
SELECT * FROM videos
|
||||||
|
WHERE id = $1
|
||||||
|
SQL
|
||||||
|
|
||||||
|
return PG_DB.query_one?(request, id, as: Video)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
def insert(video : Video)
|
def insert(video : Video)
|
||||||
REDIS_DB.set(video.id, video.info.to_json, ex: 14400)
|
DBCache.set(video: video, expire_time: 14400)
|
||||||
REDIS_DB.set(video.id + ":time", video.updated, ex: 14400)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(id)
|
def delete(id)
|
||||||
REDIS_DB.del(id)
|
DBCache.del(id)
|
||||||
REDIS_DB.del(id + ":time")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_expired
|
def delete_expired
|
||||||
|
@ -33,14 +87,6 @@ module Invidious::Database::Videos
|
||||||
end
|
end
|
||||||
|
|
||||||
def select(id : String) : Video?
|
def select(id : String) : Video?
|
||||||
if ((info = REDIS_DB.get(id)) && (time = REDIS_DB.get(id + ":time")))
|
return DBCache.get(id)
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue