Cache document update information.

pull/2826/head
maliming 6 years ago
parent 0325126eb3
commit 712029da61

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
@ -16,14 +17,17 @@ namespace Volo.Docs.Admin.Documents
private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory;
private readonly IDistributedCache<DocumentUpdateInfo> _documentUpdateCache;
public DocumentAdminAppService(IProjectRepository projectRepository,
IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory)
IDocumentSourceFactory documentStoreFactory,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache)
{
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory;
_documentUpdateCache = documentUpdateCache;
}
public async Task PullAllAsync(PullAllDocumentInput input)
@ -54,16 +58,12 @@ namespace Volo.Docs.Admin.Documents
foreach (var document in documents)
{
var oldDocument = await _documentRepository.FindAsync(document.ProjectId, document.Name,
await _documentRepository.DeleteAsync(document.ProjectId, document.Name,
document.LanguageCode,
document.Version);
if (oldDocument != null)
{
await _documentRepository.DeleteAsync(oldDocument);
}
await _documentRepository.InsertAsync(document);
await _documentRepository.InsertAsync(document, true);
await UpdateDocumentUpdateInfoCache(document);
}
}
@ -74,15 +74,21 @@ namespace Volo.Docs.Admin.Documents
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, input.Name, input.LanguageCode, input.Version);
var oldDocument = await _documentRepository.FindAsync(sourceDocument.ProjectId, sourceDocument.Name,
await _documentRepository.DeleteAsync(sourceDocument.ProjectId, sourceDocument.Name,
sourceDocument.LanguageCode, sourceDocument.Version);
await _documentRepository.InsertAsync(sourceDocument, true);
await UpdateDocumentUpdateInfoCache(sourceDocument);
}
if (oldDocument != null)
private async Task UpdateDocumentUpdateInfoCache(Document document)
{
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}";
await _documentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{
await _documentRepository.DeleteAsync(oldDocument);
}
await _documentRepository.InsertAsync(sourceDocument);
Name = document.Name,
LastUpdatedTime = document.LastUpdatedTime,
UpdatedCount = document.UpdatedCount
});
}
private async Task<Document> GetDocumentAsync(
@ -93,7 +99,8 @@ namespace Volo.Docs.Admin.Documents
{
version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version;
var source = _documentStoreFactory.Create(project.DocumentStoreType);
return await source.GetDocumentAsync(project, documentName, languageCode, version);
var document = await source.GetDocumentAsync(project, documentName, languageCode, version);
return document;
}
}
}

@ -18,6 +18,7 @@ namespace Volo.Docs.Documents
private readonly IDocumentSourceFactory _documentStoreFactory;
protected IDistributedCache<LanguageConfig> LanguageCache { get; }
protected IDistributedCache<DocumentResourceDto> ResourceCache { get; }
protected IDistributedCache<DocumentUpdateInfo> DocumentUpdateCache { get; }
protected IHostEnvironment HostEnvironment { get; }
public DocumentAppService(
IProjectRepository projectRepository,
@ -25,6 +26,7 @@ namespace Volo.Docs.Documents
IDocumentSourceFactory documentStoreFactory,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResourceDto> resourceCache,
IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IHostEnvironment hostEnvironment)
{
_projectRepository = projectRepository;
@ -32,6 +34,7 @@ namespace Volo.Docs.Documents
_documentStoreFactory = documentStoreFactory;
LanguageCache = languageCache;
ResourceCache = resourceCache;
DocumentUpdateCache = documentUpdateCache;
HostEnvironment = hostEnvironment;
}
@ -73,20 +76,18 @@ namespace Volo.Docs.Documents
var navigationNode = JsonConvert.DeserializeObject<NavigationNode>(navigationDocument.Content);
var leafs = navigationNode.Items.GetAllNodes(x => x.Items)
.Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace())
.Where(x => !x.Path.IsNullOrWhiteSpace())
.ToList();
foreach (var leaf in leafs)
{
var document = await GetDocumentWithDetailsDtoAsync(
project,
leaf.Path,
input.LanguageCode,
input.Version
);
leaf.LastUpdatedTime = document.LastUpdatedTime;
leaf.UpdatedCount = document.UpdatedCount;
var cacheKey = $"DocumentUpdateInfo{project.Id}#{leaf.Path}#{input.LanguageCode}#{input.Version}";
var documentUpdateInfo = await DocumentUpdateCache.GetAsync(cacheKey);
if (documentUpdateInfo != null)
{
leaf.LastUpdatedTime = documentUpdateInfo.LastUpdatedTime;
leaf.UpdatedCount = documentUpdateInfo.UpdatedCount;
}
}
return navigationNode;
@ -165,10 +166,19 @@ namespace Volo.Docs.Documents
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version);
await _documentRepository.InsertAsync(sourceDocument);
await _documentRepository.DeleteAsync(project.Id, sourceDocument.Name, sourceDocument.LanguageCode, sourceDocument.Version);
await _documentRepository.InsertAsync(sourceDocument, true);
Logger.LogInformation($"Document retrieved: {documentName}");
var cacheKey = $"DocumentUpdateInfo{sourceDocument.ProjectId}#{sourceDocument.Name}#{sourceDocument.LanguageCode}#{sourceDocument.Version}";
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{
Name = sourceDocument.Name,
LastUpdatedTime = sourceDocument.LastUpdatedTime,
UpdatedCount = sourceDocument.UpdatedCount
});
return CreateDocumentWithDetailsDto(project, sourceDocument);
}
@ -192,6 +202,14 @@ namespace Volo.Docs.Documents
return await GetDocumentAsync();
}
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}";
await DocumentUpdateCache.SetAsync(cacheKey, new DocumentUpdateInfo
{
Name = document.Name,
LastUpdatedTime = document.LastUpdatedTime,
UpdatedCount = document.UpdatedCount
});
return CreateDocumentWithDetailsDto(project, document);
}

@ -0,0 +1,14 @@
using System;
namespace Volo.Docs.Documents
{
[Serializable]
public class DocumentUpdateInfo
{
public virtual string Name { get; set; }
public virtual DateTime LastUpdatedTime { get; set; }
public virtual int UpdatedCount { get; set; }
}
}

@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
@ -12,5 +10,8 @@ namespace Volo.Docs.Documents
Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version,
bool includeDetails = true,
CancellationToken cancellationToken = default);
Task DeleteAsync(Guid projectId, string name, string languageCode, string version,
CancellationToken cancellationToken = default);
}
}
}

@ -25,5 +25,12 @@ namespace Volo.Docs.Documents
x.Version == version,
cancellationToken);
}
public async Task DeleteAsync(Guid projectId, string name, string languageCode, string version, CancellationToken cancellationToken = default)
{
await DeleteAsync(x =>
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode &&
x.Version == version, cancellationToken: cancellationToken);
}
}
}

@ -24,5 +24,13 @@ namespace Volo.Docs.Documents
x.LanguageCode == languageCode &&
x.Version == version, cancellationToken);
}
public async Task DeleteAsync(Guid projectId, string name, string languageCode, string version,
CancellationToken cancellationToken = default)
{
await DeleteAsync(x =>
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode &&
x.Version == version, cancellationToken: cancellationToken);
}
}
}

@ -123,10 +123,18 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
}
else
{
var badge = node.Path.IsNullOrWhiteSpace()
? ""
: "<span class='badge badge-light ml-2'>" +
(node.LastUpdatedTime + TimeSpan.FromDays(30) > DateTime.Now ? (node.UpdatedCount == 1 ? _localizer["New"] : _localizer["Upd"]) : "") + "</span>";
var badge = "";
if (!node.Path.IsNullOrWhiteSpace() && node.LastUpdatedTime.HasValue && node.LastUpdatedTime + TimeSpan.FromDays(30) > DateTime.Now)
{
if (node.UpdatedCount > 1)
{
badge = "<span class='badge badge-light ml-2'>" + _localizer["Upd"] + "</span>";
}
else
{
badge = "<span class='badge badge-primary ml-2'>" + _localizer["New"] + "</span>";
}
}
listInnerItem = string.Format(ListItemAnchor, NormalizePath(node.Path), textCss,
node.Text.IsNullOrEmpty()

@ -24,5 +24,15 @@ namespace Volo.Docs
var document = await DocumentRepository.FindAsync(DocsTestData.PorjectId, "CLI.md", "en", "2.0.0");
document.ShouldNotBeNull();
}
[Fact]
public async Task DeleteAsync()
{
(await DocumentRepository.GetListAsync()).ShouldNotBeEmpty();
await DocumentRepository.DeleteAsync(DocsTestData.PorjectId, "CLI.md", "en", "2.0.0");
(await DocumentRepository.GetListAsync()).ShouldBeEmpty();
}
}
}

Loading…
Cancel
Save