Unverified Commit fb6943e8 authored by Savorboard's avatar Savorboard Committed by GitHub

release 2.4.2 (#272)

* update version to 2.4.0

* Add version options to config file.

* update resource

* add  message version support  for dashboard

* add  message version support  for dashboard

* Support using version to isolate messages. #220

* update mongo unit tests

* update unit tests

* update unit tests

* Set default versions for consumer groups

* solve the problem of issue#181 (#237)

* Issue#235 (#238)

* solve the problem of issue#181

* solve the problem of issue#235

* refactor

* Fix the message persistence bug. #240

* using new CamelCaseNamingStrategy

* update packages to .net core 2.2

* update test framework to netcoreapp2.2

* Update .travis.yml

* update TargetFramework

* Exclude build samples project

* update version to 2.4.1

* add samples project to sln for build

* update version to 2.4.2

* Fixed PostgreSql version isolation feature bug. (#256)

* Fixed spelling errors

* modify cap publish Message to rabbitmq slow (#261)

* Startup the CAP with the BackgroundService.  #265

* update samples

* Fixed SQL query bug. #266

* update travis ci config

* update travis ci config

* adjust dashboard table column width

* adjust the consumer execution time to milliseconds
parent 94e54c21
language: csharp
sudo: required
dist: trusty
dist: xenial
solution: CAP.sln
dotnet: 2.2.100
dotnet: 2.2
mono: none
matrix:
include:
- os: linux
dist: trusty # Ubuntu 14.04
sudo: required
- os: osx
osx_image: xcode8.3 # macOS 10.12
#matrix:
# include:
# - dotnet: 2.2
# - os: linux
# dist: trusty # Ubuntu 14.04
# sudo: required
# - os: osx
# osx_image: xcode8.3 # macOS 10.12
# Run the build script
script:
- dotnet --info
- dotnet restore CAP.sln
- dotnet build CAP.sln
- dotnet test test/DotNetCore.CAP.Test/DotNetCore.CAP.Test.csproj
- dotnet test test/DotNetCore.CAP.Test/DotNetCore.CAP.Test.csproj
\ No newline at end of file
......@@ -2,7 +2,7 @@
<PropertyGroup>
<VersionMajor>2</VersionMajor>
<VersionMinor>4</VersionMinor>
<VersionPatch>1</VersionPatch>
<VersionPatch>2</VersionPatch>
<VersionQuality></VersionQuality>
<VersionPrefix>$(VersionMajor).$(VersionMinor).$(VersionPatch)</VersionPrefix>
</PropertyGroup>
......
......@@ -22,7 +22,7 @@ namespace Sample.RabbitMQ.MongoDB.Controllers
[Route("~/without/transaction")]
public IActionResult WithoutTransaction()
{
_capBus.Publish("sample.rabbitmq.mongodb", DateTime.Now);
_capBus.PublishAsync("sample.rabbitmq.mongodb", DateTime.Now);
return Ok();
}
......
......@@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
......
using Microsoft.AspNetCore.Builder;
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
......@@ -18,14 +19,14 @@ namespace Sample.RabbitMQ.MongoDB
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IMongoClient>(new MongoClient("mongodb://192.168.10.110:27017,192.168.10.110:27018,192.168.10.110:27019/?replicaSet=rs0"));
services.AddSingleton<IMongoClient>(new MongoClient(Configuration.GetConnectionString("MongoDB")));
services.AddCap(x =>
{
x.UseMongoDB("mongodb://192.168.10.110:27017,192.168.10.110:27018,192.168.10.110:27019/?replicaSet=rs0");
x.UseRabbitMQ("localhost");
x.UseMongoDB(Configuration.GetConnectionString("MongoDB"));
x.UseRabbitMQ("192.168.2.120");
x.UseDashboard();
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
......
{
"Logging": {
"LogLevel": {
"Default": "Warning"
"Default": "Debug"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"MongoDB": "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0"
"MongoDB": "mongodb://192.168.2.120:27017,192.168.2.120:27018,192.168.2.120:27019/?replicaSet=rs0"
},
"RabbitMQ": {
"HostName": "localhost",
......@@ -14,4 +14,4 @@
"UserName": "",
"Password": ""
}
}
\ No newline at end of file
}
......@@ -80,7 +80,7 @@ select count(Id) from `{0}.received` where StatusName = N'Failed';", _prefix);
if (!string.IsNullOrEmpty(queryDto.Group))
{
where += " and Group=@Group";
where += " and `Group`=@Group";
}
if (!string.IsNullOrEmpty(queryDto.Content))
......
......@@ -55,7 +55,7 @@ namespace DotNetCore.CAP.PostgreSql
private string PrepareSql()
{
return
$"INSERT INTO \"{_options.Schema}\".\"published\" (\"Id\",\"Version\",\"Name\",\"Content\",\"Retries\",\"Added\",\"ExpiresAt\",\"StatusName\")VALUES(@Id,@Version,@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);";
$"INSERT INTO \"{_options.Schema}\".\"published\" (\"Id\",\"Version\",\"Name\",\"Content\",\"Retries\",\"Added\",\"ExpiresAt\",\"StatusName\")VALUES(@Id,'{_options.Version}',@Name,@Content,@Retries,@Added,@ExpiresAt,@StatusName);";
}
private IDbConnection InitDbConnection()
......
......@@ -81,7 +81,7 @@ select count(Id) from [{0}].Received with (nolock) where StatusName = N'Failed';
if (!string.IsNullOrEmpty(queryDto.Group))
{
where += " and group=@Group";
where += " and [group]=@Group";
}
if (!string.IsNullOrEmpty(queryDto.Content))
......
......@@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Builder
/// </summary>
/// <param name="app">The <see cref="IApplicationBuilder" /> instance this method extends.</param>
/// <returns>The <see cref="IApplicationBuilder" /> instance this method extends.</returns>
public static IApplicationBuilder UseCap(this IApplicationBuilder app)
public static IApplicationBuilder UseCapDashboard(this IApplicationBuilder app)
{
if (app == null)
{
......@@ -30,10 +30,7 @@ namespace Microsoft.AspNetCore.Builder
CheckRequirement(app);
var provider = app.ApplicationServices;
var bootstrapper = provider.GetRequiredService<IBootstrapper>();
bootstrapper.BootstrapAsync();
if (provider.GetService<DashboardOptions>() != null)
{
if (provider.GetService<DiscoveryOptions>() != null)
......@@ -78,7 +75,7 @@ namespace Microsoft.AspNetCore.Builder
{
return app =>
{
app.UseCap();
app.UseCapDashboard();
next(app);
};
......
......@@ -11,6 +11,7 @@ using DotNetCore.CAP.Processor.States;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
......@@ -48,10 +49,9 @@ namespace Microsoft.Extensions.DependencyInjection
services.TryAddSingleton<IConsumerInvokerFactory, ConsumerInvokerFactory>();
services.TryAddSingleton<MethodMatcherCache>();
//Bootstrapper and Processors
//Processors
services.TryAddEnumerable(ServiceDescriptor.Singleton<IProcessingServer, ConsumerHandler>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IProcessingServer, CapProcessingServer>());
services.TryAddSingleton<IBootstrapper, DefaultBootstrapper>();
services.TryAddSingleton<IStateChanger, StateChanger>();
//Queue's message processor
......@@ -72,6 +72,7 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddSingleton(options);
//Startup and Middleware
services.AddTransient<IHostedService, DefaultBootstrapper>();
services.AddTransient<IStartupFilter, CapStartupFilter>();
return new CapBuilder(services);
......
......@@ -77,7 +77,7 @@
<table class="table">
<thead>
<tr>
<th style="width: 60px;">
<th style="width: 30px;">
<input type="checkbox" class="js-jobs-list-select-all"/>
</th>
<th>@Strings.Common_Id</th>
......
......@@ -264,7 +264,7 @@ namespace DotNetCore.CAP.Dashboard.Pages
<table class=""table"">
<thead>
<tr>
<th style=""width:60px;"">
<th style=""width:30px;"">
<input type=""checkbox"" class=""js-jobs-list-select-all"" />
</th>
<th style=""width:22%;"">");
......
......@@ -82,7 +82,7 @@
<table class="table">
<thead>
<tr>
<th style="width: 60px;">
<th style="width: 30px;">
<input type="checkbox" class="js-jobs-list-select-all"/>
</th>
<th>@Strings.Common_Id</th>
......
......@@ -289,7 +289,7 @@ namespace DotNetCore.CAP.Dashboard.Pages
<table class=""table"">
<thead>
<tr>
<th style=""width:60px;"">
<th style=""width:30px;"">
<input type=""checkbox"" class=""js-jobs-list-select-all"" />
</th>
<th>");
......
......@@ -5,89 +5,59 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace DotNetCore.CAP
{
/// <inheritdoc />
/// <summary>
/// Default implement of <see cref="T:DotNetCore.CAP.IBootstrapper" />.
/// </summary>
internal class DefaultBootstrapper : IBootstrapper
internal class DefaultBootstrapper : BackgroundService, IBootstrapper
{
private readonly IApplicationLifetime _appLifetime;
private readonly CancellationTokenSource _cts;
private readonly CancellationTokenRegistration _ctsRegistration;
private readonly ILogger<DefaultBootstrapper> _logger;
private Task _bootstrappingTask;
public DefaultBootstrapper(
ILogger<DefaultBootstrapper> logger,
IStorage storage,
IApplicationLifetime appLifetime,
IEnumerable<IProcessingServer> processors)
{
_logger = logger;
_appLifetime = appLifetime;
Storage = storage;
Processors = processors;
_cts = new CancellationTokenSource();
_ctsRegistration = appLifetime.ApplicationStopping.Register(() =>
{
_cts.Cancel();
try
{
_bootstrappingTask?.GetAwaiter().GetResult();
}
catch (OperationCanceledException ex)
{
_logger.ExpectedOperationCanceledException(ex);
}
});
}
private IStorage Storage { get; }
private IEnumerable<IProcessingServer> Processors { get; }
public Task BootstrapAsync()
{
return _bootstrappingTask = BootstrapTaskAsync();
}
private async Task BootstrapTaskAsync()
public async Task BootstrapAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("### CAP starting...");
_logger.LogDebug("### CAP background task is starting.");
await Storage.InitializeAsync(_cts.Token);
await Storage.InitializeAsync(stoppingToken);
if (_cts.IsCancellationRequested)
stoppingToken.Register(() =>
{
return;
}
_logger.LogDebug("### CAP background task is stopping.");
_appLifetime.ApplicationStopping.Register(() =>
{
foreach (var item in Processors)
{
item.Dispose();
try
{
item.Dispose();
}
catch (OperationCanceledException ex)
{
_logger.ExpectedOperationCanceledException(ex);
}
}
});
if (_cts.IsCancellationRequested)
{
return;
}
await BootstrapCoreAsync();
_ctsRegistration.Dispose();
_cts.Dispose();
_logger.LogInformation("### CAP started!");
}
}
protected virtual Task BootstrapCoreAsync()
{
......@@ -105,5 +75,10 @@ namespace DotNetCore.CAP
return Task.CompletedTask;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await BootstrapAsync(stoppingToken);
}
}
}
\ No newline at end of file
// Copyright (c) .NET Core Community. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks;
namespace DotNetCore.CAP
......@@ -10,6 +11,6 @@ namespace DotNetCore.CAP
/// </summary>
public interface IBootstrapper
{
Task BootstrapAsync();
Task BootstrapAsync(CancellationToken stoppingToken);
}
}
\ No newline at end of file
......@@ -44,20 +44,23 @@ namespace DotNetCore.CAP
public async Task<OperateResult> SendAsync(CapPublishedMessage message)
{
bool retry;
OperateResult result;
do
return await Task.Run(async () =>
{
var executedResult = await SendWithoutRetryAsync(message);
result = executedResult.Item2;
if (result == OperateResult.Success)
bool retry;
OperateResult result;
do
{
return result;
}
retry = executedResult.Item1;
} while (retry);
var executedResult = await SendWithoutRetryAsync(message);
result = executedResult.Item2;
if (result == OperateResult.Success)
{
return result;
}
retry = executedResult.Item1;
} while (retry);
return result;
return result;
});
}
private async Task<(bool, OperateResult)> SendWithoutRetryAsync(CapPublishedMessage message)
......
......@@ -89,7 +89,7 @@ namespace DotNetCore.CAP
await SetSuccessfulState(message);
_logger.ConsumerExecuted(sp.Elapsed.TotalSeconds);
_logger.ConsumerExecuted(sp.Elapsed.TotalMilliseconds);
return (false, OperateResult.Success);
}
......@@ -161,7 +161,7 @@ namespace DotNetCore.CAP
private async Task InvokeConsumerMethodAsync(CapReceivedMessage receivedMessage)
{
if (!_selector.TryGetTopicExector(receivedMessage.Name, receivedMessage.Group,
if (!_selector.TryGetTopicExecutor(receivedMessage.Name, receivedMessage.Group,
out var executor))
{
var error = $"Message can not be found subscriber. {receivedMessage} \r\n see: https://github.com/dotnetcore/CAP/issues/63";
......
......@@ -45,9 +45,9 @@ namespace DotNetCore.CAP
logger.LogError(ex, $"An exception occured while publishing a message, reason:{reason}. message id:{messageId}");
}
public static void ConsumerExecuted(this ILogger logger, double seconds)
public static void ConsumerExecuted(this ILogger logger, double milliseconds)
{
logger.LogDebug($"Consumer executed. Took: {seconds} secs.");
logger.LogDebug($"Consumer executed. Took: {milliseconds} ms.");
}
public static void ServerStarting(this ILogger logger)
......
......@@ -44,14 +44,14 @@ namespace DotNetCore.CAP.Internal
}
/// <summary>
/// Attempts to get the topic exector associated with the specified topic name and group name from the
/// Attempts to get the topic executor associated with the specified topic name and group name from the
/// <see cref="Entries" />.
/// </summary>
/// <param name="topicName">The topic name of the value to get.</param>
/// <param name="groupName">The group name of the value to get.</param>
/// <param name="matchTopic">topic exector of the value.</param>
/// <param name="matchTopic">topic executor of the value.</param>
/// <returns>true if the key was found, otherwise false. </returns>
public bool TryGetTopicExector(string topicName, string groupName,
public bool TryGetTopicExecutor(string topicName, string groupName,
out ConsumerExecutorDescriptor matchTopic)
{
if (Entries == null)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment