Optimize dist file get, add nginx x-accel support
This commit is contained in:
@@ -31,6 +31,10 @@ public class StaticFilesServerConfiguration : MareConfigurationBase
|
|||||||
public Uri CdnFullUrl { get; set; } = null;
|
public Uri CdnFullUrl { get; set; } = null;
|
||||||
[RemoteConfiguration]
|
[RemoteConfiguration]
|
||||||
public List<CdnShardConfiguration> CdnShardConfiguration { get; set; } = new();
|
public List<CdnShardConfiguration> CdnShardConfiguration { get; set; } = new();
|
||||||
|
|
||||||
|
public bool UseXAccelRedirect { get; set; } = false;
|
||||||
|
public string XAccelRedirectPrefix { get; set; } = "/_internal/mare-files/";
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
@@ -55,6 +59,7 @@ public class StaticFilesServerConfiguration : MareConfigurationBase
|
|||||||
sb.AppendLine($"{nameof(DownloadQueueSize)} => {DownloadQueueSize}");
|
sb.AppendLine($"{nameof(DownloadQueueSize)} => {DownloadQueueSize}");
|
||||||
sb.AppendLine($"{nameof(DownloadQueueReleaseSeconds)} => {DownloadQueueReleaseSeconds}");
|
sb.AppendLine($"{nameof(DownloadQueueReleaseSeconds)} => {DownloadQueueReleaseSeconds}");
|
||||||
sb.AppendLine($"{nameof(CdnShardConfiguration)} => {string.Join(", ", CdnShardConfiguration)}");
|
sb.AppendLine($"{nameof(CdnShardConfiguration)} => {string.Join(", ", CdnShardConfiguration)}");
|
||||||
|
sb.AppendLine($"{nameof(UseXAccelRedirect)} => {UseXAccelRedirect}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using MareSynchronos.API.Routes;
|
using MareSynchronos.API.Routes;
|
||||||
|
using MareSynchronosShared.Services;
|
||||||
using MareSynchronosStaticFilesServer.Services;
|
using MareSynchronosStaticFilesServer.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -9,10 +10,13 @@ namespace MareSynchronosStaticFilesServer.Controllers;
|
|||||||
public class DistributionController : ControllerBase
|
public class DistributionController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly CachedFileProvider _cachedFileProvider;
|
private readonly CachedFileProvider _cachedFileProvider;
|
||||||
|
private readonly IConfigurationService<StaticFilesServerConfiguration> _configuration;
|
||||||
|
|
||||||
public DistributionController(ILogger<DistributionController> logger, CachedFileProvider cachedFileProvider) : base(logger)
|
public DistributionController(ILogger<DistributionController> logger, CachedFileProvider cachedFileProvider,
|
||||||
|
IConfigurationService<StaticFilesServerConfiguration> configuration) : base(logger)
|
||||||
{
|
{
|
||||||
_cachedFileProvider = cachedFileProvider;
|
_cachedFileProvider = cachedFileProvider;
|
||||||
|
_configuration = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet(MareFiles.Distribution_Get)]
|
[HttpGet(MareFiles.Distribution_Get)]
|
||||||
@@ -21,10 +25,19 @@ public class DistributionController : ControllerBase
|
|||||||
{
|
{
|
||||||
_logger.LogInformation($"GetFile:{MareUser}:{file}");
|
_logger.LogInformation($"GetFile:{MareUser}:{file}");
|
||||||
|
|
||||||
var fs = await _cachedFileProvider.GetAndDownloadFileStream(file);
|
var fi = await _cachedFileProvider.GetAndDownloadFile(file);
|
||||||
if (fs == null) return NotFound();
|
if (fi == null) return NotFound();
|
||||||
|
|
||||||
return File(fs, "application/octet-stream");
|
if (_configuration.GetValueOrDefault(nameof(StaticFilesServerConfiguration.UseXAccelRedirect), false))
|
||||||
|
{
|
||||||
|
var prefix = _configuration.GetValue<string>(nameof(StaticFilesServerConfiguration.XAccelRedirectPrefix));
|
||||||
|
Response.Headers.Append("X-Accel-Redirect", Path.Combine(prefix, file));
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PhysicalFile(fi.FullName, "application/octet-stream");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("touch")]
|
[HttpPost("touch")]
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ public sealed class CachedFileProvider : IDisposable
|
|||||||
{
|
{
|
||||||
_metrics.IncGauge(MetricsAPI.GaugeFilesDownloadingFromCache);
|
_metrics.IncGauge(MetricsAPI.GaugeFilesDownloadingFromCache);
|
||||||
await DownloadTask(hash).ConfigureAwait(false);
|
await DownloadTask(hash).ConfigureAwait(false);
|
||||||
|
TryCopyFromColdStorage(hash, FilePathUtil.GetFilePath(_hotStoragePath, hash));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -177,20 +178,7 @@ public sealed class CachedFileProvider : IDisposable
|
|||||||
_downloadSemaphore.Release();
|
_downloadSemaphore.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileStream? GetLocalFileStream(string hash)
|
public async Task<FileInfo?> GetAndDownloadFile(string hash)
|
||||||
{
|
|
||||||
var fi = FilePathUtil.GetFileInfoForHash(_hotStoragePath, hash);
|
|
||||||
if (fi == null) return null;
|
|
||||||
fi.LastAccessTimeUtc = DateTime.UtcNow;
|
|
||||||
|
|
||||||
_touchService.TouchColdHash(hash);
|
|
||||||
|
|
||||||
_fileStatisticsService.LogFile(hash, fi.Length);
|
|
||||||
|
|
||||||
return new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Inheritable | FileShare.Read);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<FileStream?> GetAndDownloadFileStream(string hash)
|
|
||||||
{
|
{
|
||||||
await DownloadFileWhenRequired(hash).ConfigureAwait(false);
|
await DownloadFileWhenRequired(hash).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -214,7 +202,22 @@ public sealed class CachedFileProvider : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetLocalFileStream(hash);
|
var fi = FilePathUtil.GetFileInfoForHash(_hotStoragePath, hash);
|
||||||
|
if (fi == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
fi.LastAccessTimeUtc = DateTime.UtcNow;
|
||||||
|
_touchService.TouchColdHash(hash);
|
||||||
|
|
||||||
|
_fileStatisticsService.LogFile(hash, fi.Length);
|
||||||
|
|
||||||
|
return fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<FileStream?> GetAndDownloadFileStream(string hash)
|
||||||
|
{
|
||||||
|
var fi = await GetAndDownloadFile(hash).ConfigureAwait(false);
|
||||||
|
return new FileStream(fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Inheritable | FileShare.Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TouchColdHash(string hash)
|
public void TouchColdHash(string hash)
|
||||||
|
|||||||
Reference in New Issue
Block a user