refactor docs. closes #3381

pull/3391/head
Alper Ebicoglu 6 years ago
parent bb226783c5
commit 6757d9e742

@ -3,5 +3,10 @@
"LogoUrl": "/assets/images/Logo.png",
"ElasticSearch": {
"Url": "http://localhost:9200"
},
"Volo.Docs": {
"DocumentCacheTimeoutInterval": "24:00:00",
"DocumentResource.AbsoluteExpirationRelativeToNow": "24:00:00",
"DocumentResource.SlidingExpiration": "02:00:00"
}
}

@ -3,9 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Nest;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Caching;
@ -26,6 +28,10 @@ namespace Volo.Docs.Documents
protected IHostEnvironment HostEnvironment { get; }
private readonly IDocumentFullSearch _documentFullSearch;
private readonly DocsElasticSearchOptions _docsElasticSearchOptions;
private readonly IConfiguration _configuration;
private readonly TimeSpan _cacheTimeout;
private readonly TimeSpan _documentResourceAbsoluteExpiration;
private readonly TimeSpan _documentResourceSlidingExpiration;
public DocumentAppService(
IProjectRepository projectRepository,
@ -36,7 +42,8 @@ namespace Volo.Docs.Documents
IDistributedCache<DocumentUpdateInfo> documentUpdateCache,
IHostEnvironment hostEnvironment,
IDocumentFullSearch documentFullSearch,
IOptions<DocsElasticSearchOptions> docsElasticSearchOptions)
IOptions<DocsElasticSearchOptions> docsElasticSearchOptions,
IConfiguration configuration)
{
_projectRepository = projectRepository;
_documentRepository = documentRepository;
@ -46,7 +53,11 @@ namespace Volo.Docs.Documents
DocumentUpdateCache = documentUpdateCache;
HostEnvironment = hostEnvironment;
_documentFullSearch = documentFullSearch;
_configuration = configuration;
_docsElasticSearchOptions = docsElasticSearchOptions.Value;
_cacheTimeout = GetCacheTimeout();
_documentResourceAbsoluteExpiration = GetDocumentResourceAbsoluteExpirationTimeout();
_documentResourceSlidingExpiration = GetDocumentResourceSlidingExpirationTimeout();
}
public virtual async Task<DocumentWithDetailsDto> GetAsync(GetDocumentInput input)
@ -132,9 +143,8 @@ namespace Volo.Docs.Documents
GetResourceAsync,
() => new DistributedCacheEntryOptions
{
//TODO: Configurable?
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(6),
SlidingExpiration = TimeSpan.FromMinutes(30)
AbsoluteExpirationRelativeToNow = _documentResourceAbsoluteExpiration,
SlidingExpiration = _documentResourceSlidingExpiration
}
);
}
@ -200,48 +210,23 @@ namespace Volo.Docs.Documents
{
version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version;
async Task<DocumentWithDetailsDto> GetDocumentAsync(Document oldDocument = null)
{
Logger.LogInformation($"Not found in the cache. Requesting {documentName} from the source...");
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version, oldDocument?.LastSignificantUpdateTime);
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,
CreationTime = sourceDocument.CreationTime,
LastUpdatedTime = sourceDocument.LastUpdatedTime,
LastSignificantUpdateTime = sourceDocument.LastSignificantUpdateTime
});
return CreateDocumentWithDetailsDto(project, sourceDocument);
}
if (HostEnvironment.IsDevelopment())
{
return await GetDocumentAsync();
return await GetDocumentAsync(documentName, project, languageCode, version);
}
var document = await _documentRepository.FindAsync(project.Id, documentName, languageCode, version);
if (document == null)
{
return await GetDocumentAsync();
return await GetDocumentAsync(documentName, project, languageCode, version);
}
//Only the latest version (dev) of the document needs to update the cache.
if (!project.LatestVersionBranchName.IsNullOrWhiteSpace() &&
document.Version == project.LatestVersionBranchName &&
//TODO: Configurable cache time?
document.LastCachedTime + TimeSpan.FromHours(2) < DateTime.Now)
document.LastCachedTime + _cacheTimeout < DateTime.Now)
{
return await GetDocumentAsync(document);
return await GetDocumentAsync(documentName, project, languageCode, version, document);
}
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}";
@ -263,5 +248,62 @@ namespace Volo.Docs.Documents
documentDto.Contributors = ObjectMapper.Map<List<DocumentContributor>, List<DocumentContributorDto>>(document.Contributors);
return documentDto;
}
private async Task<DocumentWithDetailsDto> GetDocumentAsync(string documentName, Project project, string languageCode, string version, Document oldDocument = null)
{
Logger.LogInformation($"Not found in the cache. Requesting {documentName} from the source...");
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version, oldDocument?.LastSignificantUpdateTime);
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,
CreationTime = sourceDocument.CreationTime,
LastUpdatedTime = sourceDocument.LastUpdatedTime,
LastSignificantUpdateTime = sourceDocument.LastSignificantUpdateTime
});
return CreateDocumentWithDetailsDto(project, sourceDocument);
}
private TimeSpan GetCacheTimeout()
{
var value = _configuration["Volo.Docs:DocumentCacheTimeoutInterval"];
if (value.IsNullOrEmpty())
{
return TimeSpan.FromHours(6);
}
return TimeSpan.Parse(value);
}
private TimeSpan GetDocumentResourceAbsoluteExpirationTimeout()
{
var value = _configuration["Volo.Docs:DocumentResource.AbsoluteExpirationRelativeToNow"];
if (value.IsNullOrEmpty())
{
return TimeSpan.FromHours(6);
}
return TimeSpan.Parse(value);
}
private TimeSpan GetDocumentResourceSlidingExpirationTimeout()
{
var value = _configuration["Volo.Docs:DocumentResource.SlidingExpiration"];
if (value.IsNullOrEmpty())
{
return TimeSpan.FromMinutes(30);
}
return TimeSpan.Parse(value);
}
}
}

@ -3,12 +3,10 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp.Domain.Services;
using Volo.Docs.Documents;
using Volo.Docs.GitHub.Projects;
using Volo.Docs.Projects;
using Newtonsoft.Json.Linq;
using Octokit;
using Volo.Abp;
using Volo.Extensions;
@ -206,8 +204,14 @@ namespace Volo.Docs.GitHub.Documents
var url = project.GetGitHubUrl();
var ownerName = GetOwnerNameFromUrl(url);
var repositoryName = GetRepositoryNameFromUrl(url);
return await _githubRepositoryManager.GetFileCommitsAsync(ownerName, repositoryName,
version, filename, project.GetGitHubAccessTokenOrNull());
return await _githubRepositoryManager.GetFileCommitsAsync(
ownerName,
repositoryName,
version,
filename,
project.GetGitHubAccessTokenOrNull()
);
}
protected virtual string GetOwnerNameFromUrl(string url)
@ -219,7 +223,7 @@ namespace Volo.Docs.GitHub.Documents
}
catch (Exception)
{
throw new Exception($"Github url is not valid: {url}");
throw new Exception($"GitHub url is not valid: {url}");
}
}

Loading…
Cancel
Save