using Elsa.Common.Multitenancy;
using JetBrains.Annotations;
using Microsoft.Extensions.Caching.Memory;
namespace Elsa.Http.Services;
///
/// Represents a caching implementation of the IHttpWorkflowLookupService that retrieves workflows using HTTP workflow lookup service and caches the results.
///
[UsedImplicitly]
public class CachingHttpWorkflowLookupService(
IHttpWorkflowLookupService decoratedService,
IHttpWorkflowsCacheManager cacheManager,
ITenantAccessor tenantAccessor) : IHttpWorkflowLookupService
{
///
public async Task FindWorkflowAsync(string bookmarkHash, CancellationToken cancellationToken = default)
{
var tenant = tenantAccessor.Tenant;
var tenantId = tenant?.Id;
var tenantIdPrefix = !string.IsNullOrEmpty(tenantId) ? $"{tenantId}:" : string.Empty;
var key = $"{tenantIdPrefix}http-workflow:{bookmarkHash}";
var cache = cacheManager.Cache;
return await cache.GetOrCreateAsync(key, async entry =>
{
var cachingOptions = cache.CachingOptions.Value;
entry.SetSlidingExpiration(cachingOptions.CacheDuration);
entry.AddExpirationToken(cache.GetToken(cacheManager.GetTriggerChangeTokenKey(bookmarkHash)));
var result = await decoratedService.FindWorkflowAsync(bookmarkHash, cancellationToken);
if (result == null)
return null;
var workflowGraph = result.WorkflowGraph!;
var changeTokenKey = cacheManager.GetWorkflowChangeTokenKey(workflowGraph.Workflow.Identity.DefinitionId);
var changeToken = cache.GetToken(changeTokenKey);
entry.AddExpirationToken(changeToken);
return result;
});
}
}