[cache/config] Refactor cache so daap/artwork/xcode is cached in separate db's

Also change config so that the user can just configure a data directory instead
of complete path to each database.
This commit is contained in:
ejurgensen 2024-01-06 00:27:34 +01:00
parent 2efad1466f
commit c079df5da7
6 changed files with 461 additions and 338 deletions

View File

@ -52,8 +52,8 @@ general {
# IP addresses. # IP addresses.
# bind_address = "::" # bind_address = "::"
# Location of cache database # Directory where the server keeps cached data
# cache_path = "@localstatedir@/cache/@PACKAGE@/cache.db" # cache_dir = "@localstatedir@/cache/@PACKAGE@"
# DAAP requests that take longer than this threshold (in msec) get their # DAAP requests that take longer than this threshold (in msec) get their
# replies cached for next time. Set to 0 to disable caching. # replies cached for next time. Set to 0 to disable caching.
@ -203,7 +203,8 @@ library {
# Formats that should always be transcoded # Formats that should always be transcoded
# force_decode = { "format", "format" } # force_decode = { "format", "format" }
# Prefer transcode to wav (default), alac or mpeg (mp3 with the bit rate # Prefer transcode to wav (default), alac or mpeg (mp3 with the bit rate
# configured below in the streaming section) # configured below in the streaming section). Note that alac requires
# precomputing and caching mp4 headers, which takes both cpu and disk.
# prefer_format = "format" # prefer_format = "format"
# Set ffmpeg filters (similar to 'ffmpeg -af xxx') that you want the # Set ffmpeg filters (similar to 'ffmpeg -af xxx') that you want the

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ void
cache_daap_add(const char *query, const char *ua, int is_remote, int msec); cache_daap_add(const char *query, const char *ua, int is_remote, int msec);
int int
cache_daap_threshold(void); cache_daap_threshold_get(void);
/* --------------------------- Transcode cache API ------------------------- */ /* --------------------------- Transcode cache API ------------------------- */

View File

@ -55,7 +55,7 @@ static cfg_opt_t sec_general[] =
CFG_STR_LIST("trusted_networks", "{lan}", CFGF_NONE), CFG_STR_LIST("trusted_networks", "{lan}", CFGF_NONE),
CFG_BOOL("ipv6", cfg_false, CFGF_NONE), CFG_BOOL("ipv6", cfg_false, CFGF_NONE),
CFG_STR("bind_address", NULL, CFGF_NONE), CFG_STR("bind_address", NULL, CFGF_NONE),
CFG_STR("cache_path", STATEDIR "/cache/" PACKAGE "/cache.db", CFGF_NONE), CFG_STR("cache_dir", STATEDIR "/cache/" PACKAGE, CFGF_NONE),
CFG_INT("cache_daap_threshold", 1000, CFGF_NONE), CFG_INT("cache_daap_threshold", 1000, CFGF_NONE),
CFG_BOOL("speaker_autoselect", cfg_false, CFGF_NONE), CFG_BOOL("speaker_autoselect", cfg_false, CFGF_NONE),
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@ -67,6 +67,9 @@ static cfg_opt_t sec_general[] =
CFG_INT("db_pragma_cache_size", -1, CFGF_NONE), CFG_INT("db_pragma_cache_size", -1, CFGF_NONE),
CFG_STR("db_pragma_journal_mode", NULL, CFGF_NONE), CFG_STR("db_pragma_journal_mode", NULL, CFGF_NONE),
CFG_INT("db_pragma_synchronous", -1, CFGF_NONE), CFG_INT("db_pragma_synchronous", -1, CFGF_NONE),
CFG_STR("cache_daap_filename", "daap.db", CFGF_NONE),
CFG_STR("cache_artwork_filename", "artwork.db", CFGF_NONE),
CFG_STR("cache_xcode_filename", "xcode.db", CFGF_NONE),
CFG_STR("allow_origin", "*", CFGF_NONE), CFG_STR("allow_origin", "*", CFGF_NONE),
CFG_STR("user_agent", PACKAGE_NAME "/" PACKAGE_VERSION, CFGF_NONE), CFG_STR("user_agent", PACKAGE_NAME "/" PACKAGE_VERSION, CFGF_NONE),
CFG_BOOL("ssl_verifypeer", cfg_true, CFGF_NONE), CFG_BOOL("ssl_verifypeer", cfg_true, CFGF_NONE),
@ -312,6 +315,31 @@ cb_loglevel(cfg_t *config, cfg_opt_t *opt, const char *value, void *result)
return 0; return 0;
} }
// Makes sure cache_dir ends with a slash
static int
sanitize_cache_dir(cfg_t *general)
{
char *dir;
const char *s;
char *appended;
size_t len;
dir = cfg_getstr(general, "cache_dir");
len = strlen(dir);
s = strrchr(dir, '/');
if (s && (s + 1 == dir + len))
return 0;
appended = safe_asprintf("%s/", dir);
cfg_setstr(general, "cache_dir", appended);
free(appended);
return 0;
}
static int static int
conffile_expand_libname(cfg_t *lib) conffile_expand_libname(cfg_t *lib)
{ {
@ -425,7 +453,6 @@ conffile_expand_libname(cfg_t *lib)
return 0; return 0;
} }
int int
conffile_load(char *file) conffile_load(char *file)
{ {
@ -466,6 +493,14 @@ conffile_load(char *file)
runas_uid = pw->pw_uid; runas_uid = pw->pw_uid;
runas_gid = pw->pw_gid; runas_gid = pw->pw_gid;
ret = sanitize_cache_dir(cfg_getsec(cfg, "general"));
if (ret != 0)
{
DPRINTF(E_FATAL, L_CONF, "Invalid configuration of cache_dir\n");
goto out_fail;
}
lib = cfg_getsec(cfg, "library"); lib = cfg_getsec(cfg, "library");
if (cfg_size(lib, "directories") == 0) if (cfg_size(lib, "directories") == 0)

View File

@ -6892,9 +6892,6 @@ db_open(void)
int synchronous; int synchronous;
int mmap_size; int mmap_size;
if (!db_path)
return -1;
ret = sqlite3_open(db_path, &hdl); ret = sqlite3_open(db_path, &hdl);
if (ret != SQLITE_OK) if (ret != SQLITE_OK)
{ {
@ -7343,35 +7340,35 @@ db_init(void)
db_path = cfg_getstr(cfg_getsec(cfg, "general"), "db_path"); db_path = cfg_getstr(cfg_getsec(cfg, "general"), "db_path");
db_rating_updates = cfg_getbool(cfg_getsec(cfg, "library"), "rating_updates"); db_rating_updates = cfg_getbool(cfg_getsec(cfg, "library"), "rating_updates");
DPRINTF(E_LOG, L_DB, "Configured to use database file '%s'\n", db_path); DPRINTF(E_INFO, L_DB, "Configured to use database file '%s'\n", db_path);
ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
if (ret != SQLITE_OK) if (ret != SQLITE_OK)
{ {
DPRINTF(E_FATAL, L_DB, "Could not switch SQLite3 to multithread mode\n"); DPRINTF(E_FATAL, L_DB, "Could not switch SQLite3 to multithread mode\n");
DPRINTF(E_FATAL, L_DB, "Check that SQLite3 has been configured for thread-safe operations\n"); DPRINTF(E_FATAL, L_DB, "Check that SQLite3 has been configured for thread-safe operations\n");
return -1; goto error;
} }
ret = sqlite3_enable_shared_cache(1); ret = sqlite3_enable_shared_cache(1);
if (ret != SQLITE_OK) if (ret != SQLITE_OK)
{ {
DPRINTF(E_FATAL, L_DB, "Could not enable SQLite3 shared-cache mode\n"); DPRINTF(E_FATAL, L_DB, "Could not enable SQLite3 shared-cache mode\n");
return -1; goto error;
} }
ret = sqlite3_initialize(); ret = sqlite3_initialize();
if (ret != SQLITE_OK) if (ret != SQLITE_OK)
{ {
DPRINTF(E_FATAL, L_DB, "SQLite3 failed to initialize\n"); DPRINTF(E_FATAL, L_DB, "SQLite3 failed to initialize\n");
return -1; goto error;
} }
ret = db_open(); ret = db_open();
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_FATAL, L_DB, "Could not open database\n"); DPRINTF(E_FATAL, L_DB, "Could not open database\n");
return -1; goto error;
} }
ret = db_check_version(); ret = db_check_version();
@ -7380,7 +7377,7 @@ db_init(void)
DPRINTF(E_FATAL, L_DB, "Database version check errored out, incompatible database\n"); DPRINTF(E_FATAL, L_DB, "Database version check errored out, incompatible database\n");
db_perthread_deinit(); db_perthread_deinit();
return -1; goto error;
} }
else if (ret > 0) else if (ret > 0)
{ {
@ -7391,7 +7388,7 @@ db_init(void)
{ {
DPRINTF(E_FATAL, L_DB, "Could not create tables\n"); DPRINTF(E_FATAL, L_DB, "Could not create tables\n");
db_perthread_deinit(); db_perthread_deinit();
return -1; goto error;
} }
} }
@ -7409,6 +7406,9 @@ db_init(void)
rng_init(&shuffle_rng); rng_init(&shuffle_rng);
return 0; return 0;
error:
return -1;
} }
void void

View File

@ -2276,7 +2276,7 @@ daap_request(struct httpd_request *hreq)
DPRINTF(E_DBG, L_DAAP, "DAAP request handled in %d milliseconds\n", msec); DPRINTF(E_DBG, L_DAAP, "DAAP request handled in %d milliseconds\n", msec);
if (ret == DAAP_REPLY_OK && msec > cache_daap_threshold() && hreq->user_agent) if (ret == DAAP_REPLY_OK && msec > cache_daap_threshold_get() && hreq->user_agent)
cache_daap_add(hreq->uri, hreq->user_agent, ((struct daap_session *)hreq->extra_data)->is_remote, msec); cache_daap_add(hreq->uri, hreq->user_agent, ((struct daap_session *)hreq->extra_data)->is_remote, msec);
daap_reply_send(hreq, ret); // hreq is deallocted daap_reply_send(hreq, ret); // hreq is deallocted