Browse Source

Docs module cache clear

resolves https://github.com/abpframework/abp/issues/672
pull/3680/head
Yunus Emre Kalkan 7 years ago
parent
commit
669e0e9ca5
  1. 9
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/ClearCacheInput.cs
  2. 2
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs
  3. 54
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
  4. 7
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
  5. 12
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/index.js
  6. 46
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
  7. 5
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs
  8. 27
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Caching/CacheKeyGenerator.cs
  9. 3
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json

9
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/ClearCacheInput.cs

@ -0,0 +1,9 @@
using System;
namespace Volo.Docs.Admin.Documents
{
public class ClearCacheInput
{
public Guid ProjectId { get; set; }
}
}

2
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs

@ -5,6 +5,8 @@ namespace Volo.Docs.Admin.Documents
{ {
public interface IDocumentAdminAppService : IApplicationService public interface IDocumentAdminAppService : IApplicationService
{ {
Task ClearCacheAsync(ClearCacheInput input);
Task PullAllAsync(PullAllDocumentInput input); Task PullAllAsync(PullAllDocumentInput input);
Task PullAsync(PullDocumentInput input); Task PullAsync(PullDocumentInput input);

54
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs

@ -7,8 +7,10 @@ using Newtonsoft.Json;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents; using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic; using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Localization;
using Volo.Docs.Projects; using Volo.Docs.Projects;
using Volo.Extensions; using Volo.Extensions;
@ -21,19 +23,63 @@ namespace Volo.Docs.Admin.Documents
private readonly IDocumentRepository _documentRepository; private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory; private readonly IDocumentSourceFactory _documentStoreFactory;
private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache; private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache;
private readonly IDistributedCache<List<VersionInfo>> _versionCache;
private readonly IDistributedCache<LanguageConfig> _languageCache;
private readonly IDistributedCache<DocumentResource> _resourceCache;
private readonly IDocumentFullSearch _documentFullSearch; private readonly IDocumentFullSearch _documentFullSearch;
public DocumentAdminAppService(IProjectRepository projectRepository, public DocumentAdminAppService(IProjectRepository projectRepository,
IDocumentRepository documentRepository, IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory, IDocumentSourceFactory documentStoreFactory,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache, IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IDistributedCache<List<VersionInfo>> versionCache,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResource> resourceCache,
IDocumentFullSearch documentFullSearch) IDocumentFullSearch documentFullSearch)
{ {
_projectRepository = projectRepository; _projectRepository = projectRepository;
_documentRepository = documentRepository; _documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory; _documentStoreFactory = documentStoreFactory;
_documentUpdateCache = documentUpdateCache; _documentUpdateCache = documentUpdateCache;
_versionCache = versionCache;
_languageCache = languageCache;
_resourceCache = resourceCache;
_documentFullSearch = documentFullSearch; _documentFullSearch = documentFullSearch;
LocalizationResource = typeof(DocsResource);
}
public async Task ClearCacheAsync(ClearCacheInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var languageCacheKey = CacheKeyGenerator.GenerateProjectLanguageCacheKey(project);
var languageConfig = await _languageCache.GetAsync(languageCacheKey, true);
CheckNotNullCacheValue(languageConfig);
var versionCacheKey = CacheKeyGenerator.GenerateProjectVersionsCacheKey(project);
var versions = await _versionCache.GetAsync(versionCacheKey, true);
CheckNotNullCacheValue(versions);
await _languageCache.RemoveAsync(languageCacheKey, true);
await _versionCache.RemoveAsync(versionCacheKey, true);
var documents = await _documentRepository.GetListAsync();
foreach (var languageCode in languageConfig.Languages)
{
foreach (var version in versions)
{
foreach (var document in documents)
{
var documentUpdateInfoCacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, document.Name, languageCode.Code, version.Name);
await _documentUpdateCache.RemoveAsync(documentUpdateInfoCacheKey);
document.LastCachedTime = DateTime.MinValue;
await _documentRepository.UpdateAsync(document);
}
}
}
} }
public async Task PullAllAsync(PullAllDocumentInput input) public async Task PullAllAsync(PullAllDocumentInput input)
@ -116,6 +162,14 @@ namespace Volo.Docs.Admin.Documents
} }
} }
private void CheckNotNullCacheValue(object cacheValue)
{
if (cacheValue == null)
{
throw new UserFriendlyException(L["CacheNullExceptionMessage"]);
}
}
private async Task UpdateDocumentUpdateInfoCache(Document document) private async Task UpdateDocumentUpdateInfoCache(Document document)
{ {
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}";

7
modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs

@ -19,6 +19,13 @@ namespace Volo.Docs.Admin
_documentAdminAppService = documentAdminAppService; _documentAdminAppService = documentAdminAppService;
} }
[HttpPost]
[Route("ClearCache")]
public Task ClearCacheAsync(ClearCacheInput input)
{
return _documentAdminAppService.ClearCacheAsync(input);
}
[HttpPost] [HttpPost]
[Route("PullAll")] [Route("PullAll")]
public Task PullAllAsync(PullAllDocumentInput input) public Task PullAllAsync(PullAllDocumentInput input)

12
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/index.js

@ -62,6 +62,18 @@
Id: data.record.id Id: data.record.id
}); });
} }
},
{
text: l('ClearCache'),
visible: abp.auth.isGranted('Docs.Admin.Documents'),
confirmMessage: function (data) { return l('ClearCacheConfirmationMessage', data.record.name); },
action: function (data) {
volo.docs.admin.documentsAdmin
.clearCache({ projectId: data.record.id})
.then(function () {
_dataTable.ajax.reload();
});
}
} }
] ]
} }

46
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs

@ -11,6 +11,7 @@ using Nest;
using Newtonsoft.Json; using Newtonsoft.Json;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents.FullSearch.Elastic; using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Projects; using Volo.Docs.Projects;
using Volo.Extensions; using Volo.Extensions;
@ -22,8 +23,7 @@ namespace Volo.Docs.Documents
private readonly IProjectRepository _projectRepository; private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository; private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory; private readonly IDocumentSourceFactory _documentStoreFactory;
protected IDistributedCache<LanguageConfig> LanguageCache { get; } protected IDistributedCache<DocumentResource> ResourceCache { get; }
protected IDistributedCache<DocumentResourceDto> ResourceCache { get; }
protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; } protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; }
protected IHostEnvironment HostEnvironment { get; } protected IHostEnvironment HostEnvironment { get; }
private readonly IDocumentFullSearch _documentFullSearch; private readonly IDocumentFullSearch _documentFullSearch;
@ -37,8 +37,7 @@ namespace Volo.Docs.Documents
IProjectRepository projectRepository, IProjectRepository projectRepository,
IDocumentRepository documentRepository, IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory, IDocumentSourceFactory documentStoreFactory,
IDistributedCache<LanguageConfig> languageCache, IDistributedCache<DocumentResource> resourceCache,
IDistributedCache<DocumentResourceDto> resourceCache,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache, IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IHostEnvironment hostEnvironment, IHostEnvironment hostEnvironment,
IDocumentFullSearch documentFullSearch, IDocumentFullSearch documentFullSearch,
@ -48,7 +47,6 @@ namespace Volo.Docs.Documents
_projectRepository = projectRepository; _projectRepository = projectRepository;
_documentRepository = documentRepository; _documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory; _documentStoreFactory = documentStoreFactory;
LanguageCache = languageCache;
ResourceCache = resourceCache; ResourceCache = resourceCache;
DocumentUpdateCache = documentUpdateCache; DocumentUpdateCache = documentUpdateCache;
HostEnvironment = hostEnvironment; HostEnvironment = hostEnvironment;
@ -70,7 +68,7 @@ namespace Volo.Docs.Documents
input.LanguageCode, input.LanguageCode,
input.Version input.Version
); );
} }
public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input) public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input)
{ {
@ -106,7 +104,7 @@ namespace Volo.Docs.Documents
foreach (var leaf in leafs) foreach (var leaf in leafs)
{ {
var cacheKey = $"DocumentUpdateInfo{project.Id}#{leaf.Path}#{input.LanguageCode}#{input.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, leaf.Path, input.LanguageCode, input.Version);
var documentUpdateInfo = await DocumentUpdateCache.GetAsync(cacheKey); var documentUpdateInfo = await DocumentUpdateCache.GetAsync(cacheKey);
if (documentUpdateInfo != null) if (documentUpdateInfo != null)
{ {
@ -122,31 +120,31 @@ namespace Volo.Docs.Documents
public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input) public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input)
{ {
var project = await _projectRepository.GetAsync(input.ProjectId); var project = await _projectRepository.GetAsync(input.ProjectId);
var cacheKey = $"Resource@{project.ShortName}#{input.LanguageCode}#{input.Name}#{input.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentResourceCacheKey(project, input.Name, input.LanguageCode, input.Version);
input.Version = string.IsNullOrWhiteSpace(input.Version) ? project.LatestVersionBranchName : input.Version; input.Version = string.IsNullOrWhiteSpace(input.Version) ? project.LatestVersionBranchName : input.Version;
async Task<DocumentResourceDto> GetResourceAsync() async Task<DocumentResource> GetResourceAsync()
{ {
var source = _documentStoreFactory.Create(project.DocumentStoreType); var source = _documentStoreFactory.Create(project.DocumentStoreType);
var documentResource = await source.GetResource(project, input.Name, input.LanguageCode, input.Version); return await source.GetResource(project, input.Name, input.LanguageCode, input.Version);
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(documentResource);
} }
if (HostEnvironment.IsDevelopment()) if (HostEnvironment.IsDevelopment())
{ {
return await GetResourceAsync(); return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(await GetResourceAsync());
} }
return await ResourceCache.GetOrAddAsync( return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(
cacheKey, await ResourceCache.GetOrAddAsync(
GetResourceAsync, cacheKey,
() => new DistributedCacheEntryOptions GetResourceAsync,
{ () => new DistributedCacheEntryOptions
AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration, {
SlidingExpiration = _documentResourceSlidingExpiration AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration,
} SlidingExpiration = _documentResourceSlidingExpiration
); }
)
);
} }
public async Task<List<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input) public async Task<List<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input)
@ -229,7 +227,7 @@ namespace Volo.Docs.Documents
return await GetDocumentAsync(documentName, project, languageCode, version, document); return await GetDocumentAsync(documentName, project, languageCode, version, document);
} }
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, document.Name, document.LanguageCode, document.Version);
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{ {
Name = document.Name, Name = document.Name,
@ -261,7 +259,7 @@ namespace Volo.Docs.Documents
Logger.LogInformation($"Document retrieved: {documentName}"); Logger.LogInformation($"Document retrieved: {documentName}");
var cacheKey = $"DocumentUpdateInfo{sourceDocument.ProjectId}#{sourceDocument.Name}#{sourceDocument.LanguageCode}#{sourceDocument.Version}"; var cacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, sourceDocument.Name, sourceDocument.LanguageCode, sourceDocument.Version);
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{ {
Name = sourceDocument.Name, Name = sourceDocument.Name,

5
modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs

@ -7,6 +7,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Docs.Caching;
using Volo.Docs.Documents; using Volo.Docs.Documents;
namespace Volo.Docs.Projects namespace Volo.Docs.Projects
@ -51,7 +52,7 @@ namespace Volo.Docs.Projects
var project = await _projectRepository.GetByShortNameAsync(shortName); var project = await _projectRepository.GetByShortNameAsync(shortName);
var versions = await _versionCache.GetOrAddAsync( var versions = await _versionCache.GetOrAddAsync(
project.ShortName, CacheKeyGenerator.GenerateProjectVersionsCacheKey(project),
() => GetVersionsAsync(project), () => GetVersionsAsync(project),
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {
@ -116,7 +117,7 @@ namespace Volo.Docs.Projects
} }
return await LanguageCache.GetOrAddAsync( return await LanguageCache.GetOrAddAsync(
project.ShortName, CacheKeyGenerator.GenerateProjectLanguageCacheKey(project),
GetLanguagesAsync, GetLanguagesAsync,
() => new DistributedCacheEntryOptions () => new DistributedCacheEntryOptions
{ {

27
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Caching/CacheKeyGenerator.cs

@ -0,0 +1,27 @@
using Volo.Docs.Projects;
namespace Volo.Docs.Caching
{
public static class CacheKeyGenerator
{
public static string GenerateProjectLanguageCacheKey(Project project)
{
return project.ShortName;
}
public static string GenerateProjectVersionsCacheKey(Project project)
{
return project.ShortName;
}
public static string GenerateDocumentResourceCacheKey(Project project, string resourceName, string languageCode, string version)
{
return $"Resource@{project.ShortName}#{languageCode}#{resourceName}#{version}";
}
public static string GenerateDocumentUpdateInfoCacheKey(Project project, string documentName, string languageCode, string version)
{
return $"DocumentUpdateInfo{project.Id}#{documentName}#{languageCode}#{version}";
}
}
}

3
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json

@ -9,6 +9,9 @@
"Edit": "Edit", "Edit": "Edit",
"LastEditTime": "Last edit", "LastEditTime": "Last edit",
"Delete": "Delete", "Delete": "Delete",
"ClearCache": "Clear cache",
"ClearCacheConfirmationMessage": "Are you sure to clear all caches for project \"{0}\"",
"CacheNullExceptionMessage": "Cache is not available to clear!",
"InThisDocument": "In this document", "InThisDocument": "In this document",
"GoToTop": "Go to top", "GoToTop": "Go to top",
"Projects": "Project(s)", "Projects": "Project(s)",

Loading…
Cancel
Save