Merge pull request #3680 from abpframework/Docs-module-cache-clear

Docs module cache clear
pull/3691/head
Yunus Emre Kalkan 6 years ago committed by GitHub
commit ced37a387c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

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

@ -7,8 +7,10 @@ using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents;
using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Localization;
using Volo.Docs.Projects;
using Volo.Extensions;
@ -21,19 +23,52 @@ namespace Volo.Docs.Admin.Documents
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 IDistributedCache<DocumentResource> _resourceCache;
private readonly IDocumentFullSearch _documentFullSearch;
public DocumentAdminAppService(IProjectRepository projectRepository,
IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IDistributedCache<List<VersionInfo>> versionCache,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResource> resourceCache,
IDocumentFullSearch documentFullSearch)
{
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory;
_documentUpdateCache = documentUpdateCache;
_versionCache = versionCache;
_languageCache = languageCache;
_resourceCache = resourceCache;
_documentFullSearch = documentFullSearch;
LocalizationResource = typeof(DocsResource);
}
public async Task ClearCacheAsync(ClearCacheInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var languageCacheKey = CacheKeyGenerator.GenerateProjectLanguageCacheKey(project);
await _languageCache.RemoveAsync(languageCacheKey, true);
var versionCacheKey = CacheKeyGenerator.GenerateProjectVersionsCacheKey(project);
await _versionCache.RemoveAsync(versionCacheKey, true);
var documents = await _documentRepository.GetListByProjectId(project.Id);
foreach (var document in documents)
{
var documentUpdateInfoCacheKey = CacheKeyGenerator.GenerateDocumentUpdateInfoCacheKey(project, document.Name, document.LanguageCode, document.LanguageCode);
await _documentUpdateCache.RemoveAsync(documentUpdateInfoCacheKey);
document.LastCachedTime = DateTime.MinValue;
await _documentRepository.UpdateAsync(document);
}
}
public async Task PullAllAsync(PullAllDocumentInput input)

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

@ -62,6 +62,18 @@
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();
});
}
}
]
}

@ -11,6 +11,7 @@ using Nest;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Docs.Caching;
using Volo.Docs.Documents.FullSearch.Elastic;
using Volo.Docs.Projects;
using Volo.Extensions;
@ -22,8 +23,7 @@ namespace Volo.Docs.Documents
private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory;
protected IDistributedCache<LanguageConfig> LanguageCache { get; }
protected IDistributedCache<DocumentResourceDto> ResourceCache { get; }
protected IDistributedCache<DocumentResource> ResourceCache { get; }
protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; }
protected IHostEnvironment HostEnvironment { get; }
private readonly IDocumentFullSearch _documentFullSearch;
@ -37,8 +37,7 @@ namespace Volo.Docs.Documents
IProjectRepository projectRepository,
IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResourceDto> resourceCache,
IDistributedCache<DocumentResource> resourceCache,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IHostEnvironment hostEnvironment,
IDocumentFullSearch documentFullSearch,
@ -48,7 +47,6 @@ namespace Volo.Docs.Documents
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory;
LanguageCache = languageCache;
ResourceCache = resourceCache;
DocumentUpdateCache = documentUpdateCache;
HostEnvironment = hostEnvironment;
@ -70,7 +68,7 @@ namespace Volo.Docs.Documents
input.LanguageCode,
input.Version
);
}
}
public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input)
{
@ -106,7 +104,7 @@ namespace Volo.Docs.Documents
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);
if (documentUpdateInfo != null)
{
@ -122,31 +120,31 @@ namespace Volo.Docs.Documents
public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input)
{
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;
async Task<DocumentResourceDto> GetResourceAsync()
async Task<DocumentResource> GetResourceAsync()
{
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var documentResource = await source.GetResource(project, input.Name, input.LanguageCode, input.Version);
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(documentResource);
return await source.GetResource(project, input.Name, input.LanguageCode, input.Version);
}
if (HostEnvironment.IsDevelopment())
{
return await GetResourceAsync();
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(await GetResourceAsync());
}
return await ResourceCache.GetOrAddAsync(
cacheKey,
GetResourceAsync,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration,
SlidingExpiration = _documentResourceSlidingExpiration
}
);
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(
await ResourceCache.GetOrAddAsync(
cacheKey,
GetResourceAsync,
() => new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration,
SlidingExpiration = _documentResourceSlidingExpiration
}
)
);
}
public async Task<List<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input)
@ -229,7 +227,7 @@ namespace Volo.Docs.Documents
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
{
Name = document.Name,
@ -261,7 +259,7 @@ namespace Volo.Docs.Documents
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
{
Name = sourceDocument.Name,

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

@ -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}";
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@ -7,6 +8,9 @@ namespace Volo.Docs.Documents
{
public interface IDocumentRepository : IBasicRepository<Document>
{
Task<List<Document>> GetListByProjectId(Guid projectId,
CancellationToken cancellationToken = default);
Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true,
CancellationToken cancellationToken = default);

@ -9,6 +9,8 @@
"Edit": "Edit",
"LastEditTime": "Last edit",
"Delete": "Delete",
"ClearCache": "Clear cache",
"ClearCacheConfirmationMessage": "Are you sure to clear all caches for project \"{0}\"",
"InThisDocument": "In this document",
"GoToTop": "Go to top",
"Projects": "Project(s)",
@ -26,4 +28,4 @@
"UpdatedExplanation": "Updated in the last two weeks.",
"Volo.Docs.Domain:010002": "ShortName {ShortName} already exists."
}
}
}

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -15,6 +17,12 @@ namespace Volo.Docs.Documents
{
}
public async Task<List<Document>> GetListByProjectId(Guid projectId,
CancellationToken cancellationToken = default)
{
return await DbSet.Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken: cancellationToken);
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true,
CancellationToken cancellationToken = default)

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
@ -15,6 +17,11 @@ namespace Volo.Docs.Documents
{
}
public async Task<List<Document>> GetListByProjectId(Guid projectId, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().Where(d => d.ProjectId == projectId).ToListAsync(cancellationToken);
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true,
CancellationToken cancellationToken = default)

Loading…
Cancel
Save