Skip to content

Commit 2da9d81

Browse files
committed
fix: lock while getting tmdb config and add fallback
for when we're unable to get the config in some scenarios
1 parent ae73fc9 commit 2da9d81

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

Shoko.Server/Providers/TMDB/TmdbMetadataService.cs

+31-13
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ internal static TmdbMetadataService? Instance
7070

7171
private static string? _imageServerUrl = null;
7272

73+
private static readonly object _imageServerUrlLockObj = new();
74+
7375
public static string? ImageServerUrl
7476
{
7577
get
@@ -78,20 +80,36 @@ public static string? ImageServerUrl
7880
if (_imageServerUrl is not null)
7981
return _imageServerUrl;
8082

81-
// In case the server url is attempted to be accessed before the lazily initialized instance has been created, create it now if the service container is available.
82-
var instance = Instance;
83-
if (instance is null)
84-
return null;
85-
86-
try
87-
{
88-
var config = instance.UseClient(c => c.GetAPIConfiguration(), "Get API configuration").Result;
89-
return _imageServerUrl = config.Images.SecureBaseUrl;
90-
}
91-
catch (Exception ex)
83+
// Lock before getting the config, in case multiple threads are trying to get the image server url at the same time.
84+
lock (_imageServerUrlLockObj)
9285
{
93-
instance._logger.LogError(ex, "Encountered an exception while trying to find the image server url to use; {ErrorMessage}", ex.Message);
94-
throw;
86+
// Try one more time, in case it has been initialized while we were waiting.
87+
if (_imageServerUrl is not null)
88+
return _imageServerUrl;
89+
90+
// In case the server url is attempted to be accessed before the lazily initialized instance has been created, create it now if the service container is available, otherwise abort.
91+
var instance = Instance;
92+
if (instance is null)
93+
return null;
94+
95+
try
96+
{
97+
var config = instance.UseClient(c => c.GetAPIConfiguration(), "Get API configuration").Result;
98+
return _imageServerUrl = config.Images.SecureBaseUrl;
99+
}
100+
catch (Exception ex)
101+
{
102+
// If the API key is unavailable or if we can't establish a connection to the api server, then use the default image server url if we ever need to resolve the image URLs for whatever reason.
103+
if (ex is TmdbApiKeyUnavailableException || (ex is HttpRequestException httpEx && httpEx.HttpRequestError is HttpRequestError.NameResolutionError or HttpRequestError.ConnectionError or HttpRequestError.SecureConnectionError))
104+
{
105+
// If you can't be arsed to look it up yourself on their site, then here, waste more time than it's worth by decoding and reversing this string. No matter how you do it, it will be more effort compared to looking it up on their dev
106+
// site. And while you're there, go get yourself a personal API key to use. ;)
107+
char[] url = ['\x2f', '\x70', '\x2f', '\x74', '\x2f', '\x67', '\x72', '\x6f', '\x2e', '\x64', '\x62', '\x6d', '\x74', '\x2e', '\x65', '\x67', '\x61', '\x6d', '\x69', '\x2f', '\x2f', '\x3a', '\x73', '\x70', '\x74', '\x74', '\x68'];
108+
return _imageServerUrl = new string(url.Reverse().ToArray());
109+
}
110+
instance._logger.LogError(ex, "Encountered an exception while trying to find the image server url to use; {ErrorMessage}", ex.Message);
111+
throw;
112+
}
95113
}
96114
}
97115
}

0 commit comments

Comments
 (0)