From 91e90b322b15e49992c1079e09428421976fd5d7 Mon Sep 17 00:00:00 2001 From: TekH Date: Tue, 27 Oct 2026 21:57:35 +0100 Subject: [PATCH] Add caching to PdfRenderController Implemented caching in the PdfRenderController using IMemoryCache to improve performance by avoiding redundant PDF rendering. Added a new constructor parameter for IMemoryCache and a static TimeSpan field for cache duration. Introduced a private method, BuildCacheKey, to generate unique cache keys based on the SHA256 hash of PDF bytes. Updated the RenderPages method to check for cached pages before rendering and store results in the cache. --- .../Controllers/PdfRenderController.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfRenderController.cs b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfRenderController.cs index 0958384a..a85987bc 100644 --- a/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfRenderController.cs +++ b/EnvelopeGenerator.Server/EnvelopeGenerator.Server/Controllers/PdfRenderController.cs @@ -4,13 +4,17 @@ using EnvelopeGenerator.Application.Common.Interfaces.Doc; using EnvelopeGenerator.Domain.Constants; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Caching.Memory; +using System.Security.Cryptography; namespace EnvelopeGenerator.Server.Controllers; [ApiController] [Route("api/[controller]")] -public class PdfRenderController(IPdfPageImageRenderer renderer) : ControllerBase +public class PdfRenderController(IPdfPageImageRenderer renderer, IMemoryCache memoryCache) : ControllerBase { + private static readonly TimeSpan RenderCacheDuration = TimeSpan.FromMinutes(5); + // TODO(perf): Replace JSON/base64 transport for PdfBytes with application/octet-stream (or multipart) and stream-based request parsing to reduce payload size and allocation pressure for large PDFs. [HttpPost("pages")] [Authorize(AuthenticationSchemes = AuthScheme.Sender)] @@ -19,7 +23,19 @@ public class PdfRenderController(IPdfPageImageRenderer renderer) : ControllerBas if (request?.PdfBytes is not { Length: > 0 } bytes) return BadRequest("Missing PDF bytes."); + var cacheKey = BuildCacheKey(bytes); + if (memoryCache.TryGetValue(cacheKey, out IReadOnlyList? cachedPages) && cachedPages is not null) + return Ok(cachedPages); + IReadOnlyList pages = await renderer.RenderPagesAsImagesAsync(bytes, cancel); + memoryCache.Set(cacheKey, pages, RenderCacheDuration); + return Ok(pages); } + + private static string BuildCacheKey(byte[] pdfBytes) + { + var hash = Convert.ToHexString(SHA256.HashData(pdfBytes)); + return $"pdf-render:pages:v1:dpi110:{hash}"; + } }