Hello, we are currently integrating the Docs Module into our project. Is there a way to update how often the cache gets updated when fetching the documents from our Github Repository?
2 Answer(s)
-
0
Hi,
I found where it's cached after repository is pulled: https://github.com/abpframework/abp/blob/b54f4bff04181fad94f1f27a0300eda37cfbc9f0/modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs#L234
Unfortunately it's not a virtual method that you cannot easily override it but you can override the methods that call this method such as
PullAsync
andPullAllAsync
to define caching logic on your own:[Dependency(ReplaceServices = true)] [ExposeServices(typeof(IDocumentAdminAppService), typeof(DocumentAdminAppService))] public class MyDocumentAdminAppService : DocumentAdminAppService { private readonly IProjectRepository _projectRepository; private readonly IDocumentRepository _documentRepository; private readonly IDocumentSourceFactory _documentStoreFactory; private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache; private readonly IDistributedCache<List<VersionInfo>> _versionCache; private readonly IDistributedCache<LanguageConfig> _languageCache; private readonly IDocumentFullSearch _elasticSearchService; public MyDocumentAdminAppService(IProjectRepository projectRepository, IDocumentRepository documentRepository, IDocumentSourceFactory documentStoreFactory, IDistributedCache<DocumentUpdateInfo> documentUpdateCache, IDistributedCache<List<VersionInfo>> versionCache, IDistributedCache<LanguageConfig> languageCache, IDocumentFullSearch elasticSearchService) : base(projectRepository, documentRepository, documentStoreFactory, documentUpdateCache, versionCache, languageCache, elasticSearchService) { this._projectRepository = projectRepository; this._documentRepository = documentRepository; this._documentStoreFactory = documentStoreFactory; this._documentUpdateCache = documentUpdateCache; this._versionCache = versionCache; this._languageCache = languageCache; this._elasticSearchService = elasticSearchService; } private async Task UpdateDocumentUpdateInfoCache(Document document) { var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; await _documentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo { Name = document.Name, CreationTime = document.CreationTime, LastUpdatedTime = document.LastUpdatedTime }, // 👇 Define your cache options here new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); } /* * ==================== * OVERRIDE OTHER METHODS WITH ORIGINAL LOGIC BELOW * THAT ENSURES THEY CALLS THE METHOD WE WROTE ABOVE * ==================== */ public override async Task PullAsync(PullDocumentInput input) { var project = await _projectRepository.GetAsync(input.ProjectId); var source = _documentStoreFactory.Create(project.DocumentStoreType); var sourceDocument = await source.GetDocumentAsync(project, input.Name, input.LanguageCode, input.Version); await _documentRepository.DeleteAsync(sourceDocument.ProjectId, sourceDocument.Name, sourceDocument.LanguageCode, sourceDocument.Version); await _documentRepository.InsertAsync(sourceDocument, true); await UpdateDocumentUpdateInfoCache(sourceDocument); } public override async Task PullAllAsync(PullAllDocumentInput input) { var project = await _projectRepository.GetAsync(input.ProjectId); var navigationDocument = await GetDocumentAsync( project, project.NavigationDocumentName, input.LanguageCode, input.Version ); if (!DocsJsonSerializerHelper.TryDeserialize<NavigationNode>(navigationDocument.Content, out var navigation)) { throw new UserFriendlyException($"Cannot validate navigation file '{project.NavigationDocumentName}' for the project {project.Name}."); } var leafs = navigation.Items.GetAllNodes(x => x.Items) .Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace()) .ToList(); var source = _documentStoreFactory.Create(project.DocumentStoreType); var documents = new List<Document>(); foreach (var leaf in leafs) { if (leaf.Path.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || leaf.Path.StartsWith("https://", StringComparison.OrdinalIgnoreCase) || (leaf.Path.StartsWith("{{") && leaf.Path.EndsWith("}}"))) { continue; } try { var sourceDocument = await source.GetDocumentAsync(project, leaf.Path, input.LanguageCode, input.Version); documents.Add(sourceDocument); } catch (Exception e) { Logger.LogException(e); } } foreach (var document in documents) { await _documentRepository.DeleteAsync(document.ProjectId, document.Name, document.LanguageCode, document.Version); await _documentRepository.InsertAsync(document, true); await UpdateDocumentUpdateInfoCache(document); } } private async Task<Document> GetDocumentAsync( Project project, string documentName, string languageCode, string version) { version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version; var source = _documentStoreFactory.Create(project.DocumentStoreType); var document = await source.GetDocumentAsync(project, documentName, languageCode, version); return document; } }
It seems this module is not easily extended, I'll create an issue to the team to configure / customize it easily
-
0
And also this method for singular pull cachces: https://github.com/abpframework/abp/blob/d7e0ee30031eb61a59b0745c8fe81b94d4e859ef/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs#L408