Skip to content

Commit

Permalink
Cache work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Kees committed Oct 12, 2023
1 parent 36aebe6 commit bac2fa3
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 23 deletions.
44 changes: 39 additions & 5 deletions ChromiumHtmlToPdfLib/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ private enum OutputFormat
/// When <c>true</c> then caching will be enabled
/// </summary>
private bool _useCache;

/// <summary>
/// <see cref="SetDiskCache"/>
/// </summary>
private DirectoryInfo _cacheDirectory;

/// <summary>
/// <see cref="SetDiskCache"/>
/// </summary>
private long _cacheSize;
#endregion

#region Properties
Expand All @@ -193,8 +203,10 @@ private string BrowserName
{
case Enums.Browser.Chrome:
return "Google Chrome";

case Enums.Browser.Edge:
return "Microsoft Edge";

default:
throw new ArgumentOutOfRangeException();
}
Expand Down Expand Up @@ -430,6 +442,25 @@ public bool DiskCacheDisabled
set => _useCache = !value;
}

/// <summary>
/// Returns a reference to the temp directory
/// </summary>
private DirectoryInfo GetCacheDirectory
{
get
{
// TODO: Make code work
CurrentTempDirectory = _tempDirectory == null
? new DirectoryInfo(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()))
: new DirectoryInfo(Path.Combine(_tempDirectory, Guid.NewGuid().ToString()));

if (!CurrentTempDirectory.Exists)
CurrentTempDirectory.Create();

return CurrentTempDirectory;
}
}

/// <summary>
/// The timeout in milliseconds when waiting for a websocket to open
/// </summary>
Expand Down Expand Up @@ -776,7 +807,7 @@ public void ResetChromiumArguments()

_defaultChromiumArgument = new List<string>();

if (UseOldHeaslessMode)
if (UseOldHeadlessMode)
AddChromiumArgument("--headless");
else
AddChromiumArgument("--headless", "new");
Expand Down Expand Up @@ -999,13 +1030,14 @@ public void SetUserAgent(string value)
/// <param name="size">The maximum size in megabytes for the cache directory, <c>null</c> to let Chromium decide</param>
/// <remarks>
/// You can not share a cache folder between multiple instances that are running at the same time because a Google
/// Chrome
/// or Microsoft Edge instance locks the cache for it self. If you want to use caching in a multi threaded environment
/// then assign a unique cache folder to each running Google Chrome or Microsoft Edge instance
/// Chrome or Microsoft Edge instance locks the cache for it self. If you want to use caching in a multi threaded
/// environment then assign a unique cache folder to each running Google Chrome or Microsoft Edge instance
/// </remarks>
public void SetDiskCache(string directory, long? size)
{
if (!Directory.Exists(directory))
_cacheDirectory = new DirectoryInfo(directory);

if (!_cacheDirectory.Exists)
throw new DirectoryNotFoundException($"The directory '{directory}' does not exists");

AddChromiumArgument("--disk-cache-dir", directory.TrimEnd('\\', '/'));
Expand All @@ -1015,6 +1047,8 @@ public void SetDiskCache(string directory, long? size)
if (size.Value <= 0)
throw new ArgumentException("Has to be a value of 1 or greater", nameof(size));

_cacheSize = size.Value * 1024 * 1024;

AddChromiumArgument("--disk-cache-size", (size.Value * 1024 * 1024).ToString());
}

Expand Down
16 changes: 15 additions & 1 deletion ChromiumHtmlToPdfLib/Helpers/DocumentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ internal class DocumentHelper : IDisposable
private readonly Stopwatch _stopwatch;

private readonly int _imageLoadTimeout;

/// <summary>
/// The cache folder
/// </summary>
readonly DirectoryInfo _cacheFolder;

/// <summary>
/// The cache size
/// </summary>
private readonly long _cacheSize;
#endregion

#region Properties
Expand Down Expand Up @@ -144,12 +154,16 @@ public DocumentHelper(DirectoryInfo tempDirectory,
WebProxy webProxy,
bool useCache,
int? imageLoadTimeout,
ILogger logger)
ILogger logger,
DirectoryInfo cacheFolder,
long cacheSize)
{
_tempDirectory = tempDirectory;
_webProxy = webProxy;
_useCache = useCache;
_logger = logger;
_cacheFolder = cacheFolder;
_cacheSize = cacheSize;

if (!imageLoadTimeout.HasValue) return;
_imageLoadTimeout = imageLoadTimeout.Value;
Expand Down
63 changes: 46 additions & 17 deletions ChromiumHtmlToPdfLib/Helpers/FileCacheHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,38 @@ internal class FileCacheHandler : HttpClientHandler
/// <summary>
/// The cache folder
/// </summary>
DirectoryInfo _cacheFolder;
readonly DirectoryInfo _cacheFolder;

private readonly long _cacheSize;
#endregion

internal FileCacheHandler(HttpClientHandler httpClientHandler, DirectoryInfo cacheFolder)
internal FileCacheHandler(HttpClientHandler httpClientHandler, FileSystemInfo cacheFolder, long cacheSize)
{
_httpClientHandler = httpClientHandler;
_cacheFolder = cacheFolder;
_cacheFolder = new DirectoryInfo(Path.Combine(cacheFolder.FullName, "HttpClientHandler"));
_cacheSize = cacheSize;

if (!_cacheFolder.Exists)
_cacheFolder.Create();
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var hash = GetMd5HashFromString(request.RequestUri.ToString());
var cachedFile = new FileInfo(Path.Combine(_cacheFolder.FullName, hash));

if (File.Exists(hash))
{
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new FileStream(hash, FileMode.OpenOrCreate)),
ReasonPhrase = "Loaded from cache"
};
return Task.FromResult(response);
}
if (!cachedFile.Exists)
return base.SendAsync(request, cancellationToken);

// TODO: Cache file

var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StreamContent(new FileStream(hash, FileMode.OpenOrCreate)),
Content = new StreamContent(cachedFile.OpenRead()),
ReasonPhrase = "Loaded from cache"
};

return Task.FromResult(response);

//throw new NotImplementedException();
return base.SendAsync(request, cancellationToken);
return Task.FromResult(response);
}

#region GetMd5HashFromString
Expand All @@ -71,4 +70,34 @@ public string GetMd5HashFromString(string value)
return bytes.Aggregate(string.Empty, (current, b) => current + b.ToString("X2"));
}
#endregion


private static void DeleteOldestFilesIfFolderExceedsSizeLimit(string folderPath, long maxSizeInBytes)
{
var directoryInfo = new DirectoryInfo(folderPath);
var files = directoryInfo.GetFiles();

var currentFolderSize = files.Sum(file => file.Length);

if (currentFolderSize <= maxSizeInBytes) return;
{
var oldestFiles = files.OrderBy(file => file.CreationTime).ToArray();

foreach (var file in oldestFiles)
{
try
{
file.Delete();
currentFolderSize -= file.Length;

if (currentFolderSize <= maxSizeInBytes)
break;
}
catch (Exception exception)
{
throw new Exception($"Failed to delete file: {file.FullName} - {exception.Message}");
}
}
}
}
}

0 comments on commit bac2fa3

Please sign in to comment.