< Summary

Information
Class: Elsa.Workflows.Management.Services.CachingWorkflowDefinitionService
Assembly: Elsa.Workflows.Management
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Management/Services/CachingWorkflowDefinitionService.cs
Line coverage
100%
Covered lines: 109
Uncovered lines: 0
Coverable lines: 109
Total lines: 207
Line coverage: 100%
Branch coverage
81%
Covered branches: 13
Total branches: 16
Branch coverage: 81.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Management/Services/CachingWorkflowDefinitionService.cs

#LineLine coverage
 1using Elsa.Common.Models;
 2using Elsa.Workflows.Management.Entities;
 3using Elsa.Workflows.Management.Filters;
 4using Elsa.Workflows.Management.Models;
 5using Elsa.Workflows.Models;
 6using JetBrains.Annotations;
 7using Microsoft.Extensions.Caching.Memory;
 8
 9namespace Elsa.Workflows.Management.Services;
 10
 11/// <summary>
 12/// Decorates an <see cref="IWorkflowDefinitionService"/> with caching capabilities.
 13/// </summary>
 14[UsedImplicitly]
 48015public class CachingWorkflowDefinitionService(
 48016    IWorkflowDefinitionService decoratedService,
 48017    IWorkflowDefinitionCacheManager cacheManager,
 48018    IWorkflowDefinitionStore workflowDefinitionStore,
 48019    IMaterializerRegistry materializerRegistry) : IWorkflowDefinitionService
 20{
 21    /// <inheritdoc />
 22    public Task<WorkflowGraph> MaterializeWorkflowAsync(WorkflowDefinition definition, CancellationToken cancellationTok
 23    {
 154824        return decoratedService.MaterializeWorkflowAsync(definition, cancellationToken);
 25    }
 26
 27    /// <inheritdoc />
 28    public async Task<WorkflowDefinition?> FindWorkflowDefinitionAsync(string definitionId, VersionOptions versionOption
 29    {
 330        var cacheKey = cacheManager.CreateWorkflowDefinitionVersionCacheKey(definitionId, versionOptions);
 31
 332        return await FindFromCacheAsync(cacheKey,
 333            () => decoratedService.FindWorkflowDefinitionAsync(definitionId, versionOptions, cancellationToken),
 634            x => x.DefinitionId);
 335    }
 36
 37    /// <inheritdoc />
 38    public async Task<WorkflowDefinition?> FindWorkflowDefinitionAsync(string definitionVersionId, CancellationToken can
 39    {
 140        var cacheKey = cacheManager.CreateWorkflowDefinitionVersionCacheKey(definitionVersionId);
 141        return await FindFromCacheAsync(cacheKey,
 142            () => decoratedService.FindWorkflowDefinitionAsync(definitionVersionId, cancellationToken),
 243            x => x.DefinitionId);
 144    }
 45
 46    /// <inheritdoc />
 47    public Task<WorkflowDefinition?> FindWorkflowDefinitionAsync(WorkflowDefinitionHandle handle, CancellationToken canc
 48    {
 149        var filter = handle.ToFilter();
 150        return FindWorkflowDefinitionAsync(filter, cancellationToken);
 51    }
 52
 53    /// <inheritdoc />
 54    public async Task<WorkflowDefinition?> FindWorkflowDefinitionAsync(WorkflowDefinitionFilter filter, CancellationToke
 55    {
 43456        var cacheKey = cacheManager.CreateWorkflowDefinitionFilterCacheKey(filter);
 43457        return await FindFromCacheAsync(cacheKey,
 10658            () => decoratedService.FindWorkflowDefinitionAsync(filter, cancellationToken),
 54059            x => x.DefinitionId);
 43460    }
 61
 62    /// <inheritdoc />
 63    public async Task<WorkflowGraph?> FindWorkflowGraphAsync(string definitionId, VersionOptions versionOptions, Cancell
 64    {
 3665        var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(definitionId, versionOptions);
 3666        return await FindFromCacheAsync(cacheKey,
 1967            () => decoratedService.FindWorkflowGraphAsync(definitionId, versionOptions, cancellationToken),
 5468            x => x.Workflow.Identity.DefinitionId);
 3469    }
 70
 71    /// <inheritdoc />
 72    public async Task<WorkflowGraph?> FindWorkflowGraphAsync(string definitionVersionId, CancellationToken cancellationT
 73    {
 28274        var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(definitionVersionId);
 28275        return await FindFromCacheAsync(cacheKey,
 9576            () => decoratedService.FindWorkflowGraphAsync(definitionVersionId, cancellationToken),
 37777            x => x.Workflow.Identity.DefinitionId);
 28278    }
 79
 80    /// <inheritdoc />
 81    public Task<WorkflowGraph?> FindWorkflowGraphAsync(WorkflowDefinitionHandle definitionHandle, CancellationToken canc
 82    {
 183        var filter = definitionHandle.ToFilter();
 184        return FindWorkflowGraphAsync(filter, cancellationToken);
 85    }
 86
 87    /// <inheritdoc />
 88    public async Task<WorkflowGraph?> FindWorkflowGraphAsync(WorkflowDefinitionFilter filter, CancellationToken cancella
 89    {
 11190        var cacheKey = cacheManager.CreateWorkflowFilterCacheKey(filter);
 11191        return await FindFromCacheAsync(cacheKey,
 9892            () => decoratedService.FindWorkflowGraphAsync(filter, cancellationToken),
 20993            x => x.Workflow.Identity.DefinitionId);
 11194    }
 95
 96    /// <inheritdoc />
 97    public async Task<IEnumerable<WorkflowGraph>> FindWorkflowGraphsAsync(WorkflowDefinitionFilter filter, CancellationT
 98    {
 399        var workflowDefinitions = await workflowDefinitionStore.FindManyAsync(filter, cancellationToken);
 3100        var workflowGraphs = new List<WorkflowGraph>();
 12101        foreach (var workflowDefinition in workflowDefinitions)
 102        {
 3103            var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(workflowDefinition.Id);
 3104            var workflowGraph = await GetFromCacheAsync(
 3105                cacheKey,
 2106                async () => await MaterializeWorkflowAsync(workflowDefinition, cancellationToken),
 5107                wf => wf.Workflow.Identity.DefinitionId);
 3108            workflowGraphs.Add(workflowGraph);
 109        }
 110
 3111        return workflowGraphs;
 3112    }
 113
 114    /// <inheritdoc />
 115    public async Task<WorkflowGraphFindResult> TryFindWorkflowGraphAsync(string definitionId, VersionOptions versionOpti
 116    {
 1117        var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(definitionId, versionOptions);
 1118        var result = await GetFromCacheAsync(cacheKey,
 1119            () => decoratedService.TryFindWorkflowGraphAsync(definitionId, versionOptions, cancellationToken),
 2120            x => x.WorkflowDefinition?.DefinitionId);
 121
 1122        return result;
 1123    }
 124
 125    /// <inheritdoc />
 126    public async Task<WorkflowGraphFindResult> TryFindWorkflowGraphAsync(string definitionVersionId, CancellationToken c
 127    {
 1128        var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(definitionVersionId);
 1129        var result = await GetFromCacheAsync(cacheKey,
 1130            () => decoratedService.TryFindWorkflowGraphAsync(definitionVersionId, cancellationToken),
 2131            x => x.WorkflowDefinition?.DefinitionId);
 132
 1133        return result;
 1134    }
 135
 136    /// <inheritdoc />
 137    public Task<WorkflowGraphFindResult> TryFindWorkflowGraphAsync(WorkflowDefinitionHandle definitionHandle, Cancellati
 138    {
 207139        var filter = definitionHandle.ToFilter();
 207140        return TryFindWorkflowGraphAsync(filter, cancellationToken);
 141    }
 142
 143    /// <inheritdoc />
 144    public async Task<WorkflowGraphFindResult> TryFindWorkflowGraphAsync(WorkflowDefinitionFilter filter, CancellationTo
 145    {
 208146        var cacheKey = cacheManager.CreateWorkflowFilterCacheKey(filter);
 208147        var result = await GetFromCacheAsync(cacheKey,
 92148            () => decoratedService.TryFindWorkflowGraphAsync(filter, cancellationToken),
 300149            x => x.WorkflowDefinition?.DefinitionId);
 150
 208151        return result;
 208152    }
 153
 154    /// <inheritdoc />
 155    public async Task<IEnumerable<WorkflowGraphFindResult>> TryFindWorkflowGraphsAsync(WorkflowDefinitionFilter filter, 
 156    {
 3157        var workflowDefinitions = await workflowDefinitionStore.FindManyAsync(filter, cancellationToken);
 3158        var results = new List<WorkflowGraphFindResult>();
 14159        foreach (var workflowDefinition in workflowDefinitions)
 160        {
 4161            if (!materializerRegistry.IsMaterializerAvailable(workflowDefinition.MaterializerName))
 162            {
 2163                var unavailableResult = new WorkflowGraphFindResult(workflowDefinition, null);
 2164                results.Add(unavailableResult);
 2165                continue;
 166            }
 167
 2168            var cacheKey = cacheManager.CreateWorkflowVersionCacheKey(workflowDefinition.Id);
 2169            var workflowGraph = await FindFromCacheAsync(
 2170                cacheKey,
 2171                async () => await MaterializeWorkflowAsync(workflowDefinition, cancellationToken),
 4172                wf => wf.Workflow.Identity.DefinitionId);
 173
 2174            var result = new WorkflowGraphFindResult(workflowDefinition, workflowGraph);
 2175            results.Add(result);
 2176        }
 177
 3178        return results;
 3179    }
 180
 181    private async Task<T?> FindFromCacheAsync<T>(string cacheKey, Func<Task<T?>> getObjectFunc, Func<T, string> getChang
 182    {
 869183        return await GetFromCacheAsync(
 869184            cacheKey,
 869185            getObjectFunc,
 1193186            obj => obj != null ? getChangeTokenKeyFunc(obj) : null);
 867187    }
 188
 189    private async Task<T> GetFromCacheAsync<T>(string cacheKey, Func<Task<T>> getObjectFunc, Func<T, string?> getChangeT
 190    {
 1082191        var cache = cacheManager.Cache;
 1082192        return await cache.GetOrCreateAsync(cacheKey, async entry =>
 1082193        {
 420194            entry.SetAbsoluteExpiration(cache.CachingOptions.Value.CacheDuration);
 420195            var obj = await getObjectFunc();
 420196            var changeTokenKeyInput = getChangeTokenKeyFunc(obj);
 1082197
 420198            if (changeTokenKeyInput != null)
 1082199            {
 419200                var changeTokenKey = cacheManager.CreateWorkflowDefinitionChangeTokenKey(changeTokenKeyInput);
 419201                entry.AddExpirationToken(cache.GetToken(changeTokenKey));
 1082202            }
 1082203
 420204            return obj;
 1502205        });
 1080206    }
 207}