Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Grpc.Core for netcoreapp3.1 and net48 #93

Merged
merged 21 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3738f84
dual target netcoreapp3.1 and net5.0
thefringeninja Jan 4, 2021
27ba7fc
add gossip support to grpc.core implementation
thefringeninja Jan 5, 2021
fe45d52
update scan vulnerabilities tool
thefringeninja Jan 5, 2021
06aad41
use channel per node for grpc.core implementations
thefringeninja Jan 6, 2021
1e913d1
add net48 support
thefringeninja Jan 6, 2021
9672b43
remove/obsolete createHttpMessageHandler
thefringeninja Jan 6, 2021
3ad6b3c
add reasonable timeouts to gh action jobs
thefringeninja Jan 7, 2021
a2d45b8
await ack/nack in tests to avoid 'Only one write can be pending at a …
thefringeninja Jan 7, 2021
567f80d
grpc.core may use unavailable instead of deadline exceeded
thefringeninja Jan 7, 2021
3489103
include framework in test results file names
thefringeninja Jan 7, 2021
38774a3
skip installing frameworks for targets that don't need it
thefringeninja Jan 7, 2021
8ea4c58
implement DisposeAsync for better cleanup
thefringeninja Jan 7, 2021
a19d48e
support keep alives
thefringeninja Jan 8, 2021
92804a7
skip flakey regression on net .framework
thefringeninja Jan 11, 2021
3b75d24
downgrade to gRPC 2.32.1
thefringeninja Jan 13, 2021
9d24daa
added dns name to generated certificates
thefringeninja Jan 14, 2021
f73f2c1
remove unused test project
thefringeninja Jan 14, 2021
18ba7c9
improve array shuffling
thefringeninja Jan 14, 2021
57b5f23
obsolete GossipOverHttps
thefringeninja Jan 18, 2021
4dceb12
don't use CallCredentials when none supplied
thefringeninja Jan 18, 2021
22f4075
remove duplicate compiler directive
thefringeninja Jan 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
]
},
"dotnet-retire": {
"version": "4.0.1",
"version": "5.0.0",
"commands": [
"dotnet-retire"
]
Expand All @@ -21,4 +21,4 @@
]
}
}
}
}
53 changes: 35 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ on:
tags:
- v*

env:
DOTNET_SDK_VERSION: 3.1.302
jobs:
vulnerability-scan:
timeout-minutes: 5
strategy:
fail-fast: false
matrix:
sdk: [5.0-focal, 3.1-bionic]
runs-on: ubuntu-latest
name: ci/github/scan-vulnerabilities
container: mcr.microsoft.com/dotnet/core/sdk:3.1-bionic
name: scan-vulnerabilities/${{ matrix.sdk }}
container: mcr.microsoft.com/dotnet/sdk:${{ matrix.sdk }}
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -23,16 +26,18 @@ jobs:
dotnet tool restore
dotnet restore
dotnet tool run dotnet-retire
build:
build-dotnet:
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
framework: [netcoreapp3.1, net5.0, net48]
os: [ubuntu-18.04]
test: ["", .Streams, .PersistentSubscriptions, .Operations, .UserManagement, .ProjectionManagement]
configuration: [release]
docker-tag: ['ci']
runs-on: ${{ matrix.os }}
name: ci/github/build-${{ matrix.os }}/EventStore.Client${{ matrix.test }}
name: build-${{ matrix.os }}/${{ matrix.framework }}/EventStore.Client${{ matrix.test }}
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -49,24 +54,31 @@ jobs:
shell: bash
run: |
docker pull docker.pkg.github.com/eventstore/eventstore/eventstore:${{ matrix.docker-tag }}
- name: Install Dotnet
- name: Install netcoreapp3.1
uses: actions/setup-dotnet@v1
if: matrix.framework == 'netcoreapp3.1'
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
dotnet-version: 3.1.x
- name: Install net5.0
uses: actions/setup-dotnet@v1
if: matrix.framework == 'net5.0'
with:
dotnet-version: 5.0.x
- name: Compile
shell: bash
run: |
dotnet build --configuration ${{ matrix.configuration }} src/EventStore.Client${{ matrix.test }}
dotnet build --configuration ${{ matrix.configuration }} --framework ${{ matrix.framework }} src/EventStore.Client${{ matrix.test }}
- name: Run Tests
shell: bash
env:
ES_DOCKER_TAG: ${{ matrix.docker-tag }}
run: |
./gencert.sh
dotnet test --configuration ${{ matrix.configuration }} --blame \
--logger:html --logger:trx --logger:"console;verbosity=normal" \
--results-directory=$(pwd)/test-results/test/EventStore.Client${{ matrix.test }}.Tests \
test/EventStore.Client${{ matrix.test }}.Tests
--logger:html --logger:trx --logger:"console;verbosity=normal" \
--results-directory=$(pwd)/test-results/test/EventStore.Client${{ matrix.test }}.Tests \
--framework ${{ matrix.framework }} \
test/EventStore.Client${{ matrix.test }}.Tests
- name: Collect Test Results
shell: bash
if: always()
Expand All @@ -77,17 +89,18 @@ jobs:
if: always()
with:
path: test-results.html
name: test-results-${{ matrix.configuration }}-EventStore.Client${{ matrix.test }}.html
name: test-results-${{ matrix.configuration }}-${{ matrix.framework }}-EventStore.Client${{ matrix.test }}.html
- name: Publish Test Results (All)
uses: actions/upload-artifact@v1
if: always()
with:
name: test-results-${{ matrix.configuration }}-EventStore.Client${{ matrix.test }}
name: test-results-${{ matrix.configuration }}-${{ matrix.framework }}-EventStore.Client${{ matrix.test }}
path: test-results
publish:
needs: [vulnerability-scan, build]
timeout-minutes: 5
needs: [vulnerability-scan, build-dotnet]
runs-on: ubuntu-latest
name: ci/github/publish
name: publish
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -102,10 +115,14 @@ jobs:
- shell: bash
run: |
git fetch --prune --unshallow
- name: Setup Dotnet
- name: Install netcoreapp3.1
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x
- name: Install net5.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ env.DOTNET_SDK_VERSION }}
dotnet-version: 5.0.x
- name: Dotnet Pack
shell: bash
run: |
Expand Down
8 changes: 8 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net48;netcoreapp3.1;net5.0</TargetFrameworks>
<Platform>x64</Platform>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Nullable>disable</Nullable>
Expand All @@ -13,8 +14,15 @@
<RootNamespace>EventStore.Client</RootNamespace>
<UseLinkBase>true</UseLinkBase>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net48' Or '$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>$(DefineConstants);GRPC_CORE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NETStandard.Library" Version="2.0.3"/>
<PackageReference Include="System.Net.Http" Version="4.3.4"/>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<PackageReference Include="IndexRange" Version="1.0.0" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
4 changes: 3 additions & 1 deletion gencert.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

mkdir -p certs

chmod 0755 ./certs

docker pull docker.pkg.github.com/eventstore/es-gencert-cli/es-gencert-cli:1.0.1

docker run --rm --volume $PWD/certs:/tmp --user $(id -u):$(id -g) docker.pkg.github.com/eventstore/es-gencert-cli/es-gencert-cli:1.0.1 create-ca -out /tmp/ca

docker run --rm --volume $PWD/certs:/tmp --user $(id -u):$(id -g) docker.pkg.github.com/eventstore/es-gencert-cli/es-gencert-cli:1.0.1 create-node -ca-certificate /tmp/ca/ca.crt -ca-key /tmp/ca/ca.key -out /tmp/node -ip-addresses 127.0.0.1
docker run --rm --volume $PWD/certs:/tmp --user $(id -u):$(id -g) docker.pkg.github.com/eventstore/es-gencert-cli/es-gencert-cli:1.0.1 create-node -ca-certificate /tmp/ca/ca.crt -ca-key /tmp/ca/ca.key -out /tmp/node -ip-addresses 127.0.0.1 -dns-names localhost

chmod 0755 -R ./certs
8 changes: 3 additions & 5 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"/>
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;netstandard2.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="$(MSBuildProjectName) != 'EventStore.Client'">
<ESPackageIdSuffix>$(MSBuildProjectName.Remove(0,18))</ESPackageIdSuffix>
<ESProto>$(ESPackageIdSuffix.ToLower()).proto</ESProto>
Expand All @@ -28,6 +25,7 @@
<Copyright>Copyright 2012-2020 Event Store Ltd</Copyright>
<MinVerTagPrefix>v</MinVerTagPrefix>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GrpcPackageVersion>2.33.1</GrpcPackageVersion>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE.md" Pack="true" PackagePath="\"/>
Expand All @@ -38,11 +36,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Grpc.Tools" Version="2.30.0">
<PackageReference Include="Grpc.Tools" Version="$(GrpcPackageVersion)">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="MinVer" Version="2.3.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="2.4.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Compile Include="../EventStore.Client.Common/**/*.cs"/>
Expand Down
16 changes: 16 additions & 0 deletions src/EventStore.Client.Common/AsyncStreamReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;

#if GRPC_CORE
namespace Grpc.Core {
internal static class AsyncStreamReaderExtensions {
public static async IAsyncEnumerable<T> ReadAllAsync<T>(this IAsyncStreamReader<T> reader,
[EnumeratorCancellation] CancellationToken cancellationToken = default) {
while (await reader.MoveNext(cancellationToken).ConfigureAwait(false)) {
yield return reader.Current;
}
}
}
}
#endif
13 changes: 13 additions & 0 deletions src/EventStore.Client.Common/DeconstructionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Collections.Generic;
#nullable enable
namespace EventStore.Client {
#if NETFRAMEWORK
internal static class DeconstructionExtensions {
public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> source, out TKey key,
out TValue value) {
key = source.Key;
value = source.Value;
}
}
#endif
}
12 changes: 10 additions & 2 deletions src/EventStore.Client.Common/EpochExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@
#nullable enable
namespace EventStore.Client {
internal static class EpochExtensions {
private static readonly DateTime UnixEpoch =
#if NETFRAMEWORK
new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
#else
DateTime.UnixEpoch
#endif
;

public static DateTime FromTicksSinceEpoch(this long value) =>
new DateTime(DateTime.UnixEpoch.Ticks + value, DateTimeKind.Utc);
new DateTime(UnixEpoch.Ticks + value, DateTimeKind.Utc);

public static long ToTicksSinceEpoch(this DateTime value) =>
(value - DateTime.UnixEpoch).Ticks;
(value - UnixEpoch).Ticks;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ public static CallOptions Create(EventStoreClientSettings settings,
cancellationToken: cancellationToken,
deadline: DeadlineAfter(operationOptions.TimeoutAfter),
headers: new Metadata(),
credentials: CallCredentials.FromInterceptor(async (context, metadata) => {
var credentials = settings.DefaultCredentials ?? userCredentials;
credentials: (settings.DefaultCredentials ?? userCredentials) == null
? null
: CallCredentials.FromInterceptor(async (context, metadata) => {
var credentials = settings.DefaultCredentials ?? userCredentials;

if (credentials == null) {
return;
}

var authorizationHeader = await settings.OperationOptions
.GetAuthenticationHeaderValue(credentials, CancellationToken.None)
.ConfigureAwait(false);
metadata.Add(Constants.Headers.Authorization, authorizationHeader);
})
var authorizationHeader = await settings.OperationOptions
.GetAuthenticationHeaderValue(credentials!, CancellationToken.None)
.ConfigureAwait(false);
metadata.Add(Constants.Headers.Authorization, authorizationHeader);
})
);

private static DateTime? DeadlineAfter(TimeSpan? timeoutAfter) => !timeoutAfter.HasValue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public partial class EventStoreOperationsClient {
public async Task ShutdownAsync(
UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
await _client.ShutdownAsync(EmptyResult,
await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).ShutdownAsync(EmptyResult,
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
}

Expand All @@ -29,7 +30,8 @@ await _client.ShutdownAsync(EmptyResult,
public async Task MergeIndexesAsync(
UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
await _client.MergeIndexesAsync(EmptyResult,
await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).MergeIndexesAsync(EmptyResult,
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
}

Expand All @@ -42,7 +44,8 @@ await _client.MergeIndexesAsync(EmptyResult,
public async Task ResignNodeAsync(
UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
await _client.ResignNodeAsync(EmptyResult,
await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).ResignNodeAsync(EmptyResult,
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
}

Expand All @@ -56,7 +59,9 @@ await _client.ResignNodeAsync(EmptyResult,
public async Task SetNodePriorityAsync(int nodePriority,
UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
await _client.SetNodePriorityAsync(new SetNodePriorityReq {Priority = nodePriority},
await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).SetNodePriorityAsync(
new SetNodePriorityReq {Priority = nodePriority},
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
}

Expand All @@ -68,7 +73,9 @@ await _client.SetNodePriorityAsync(new SetNodePriorityReq {Priority = nodePriori
/// <returns></returns>
public async Task RestartPersistentSubscriptions(UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
await _client.RestartPersistentSubscriptionsAsync(EmptyResult,
await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).RestartPersistentSubscriptionsAsync(
EmptyResult,
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ public async Task<DatabaseScavengeResult> StartScavengeAsync(
throw new ArgumentOutOfRangeException(nameof(startFromChunk));
}

var result = await _client.StartScavengeAsync(new StartScavengeReq {
Options = new StartScavengeReq.Types.Options {
ThreadCount = threadCount,
StartFromChunk = startFromChunk
}
}, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
var result = await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).StartScavengeAsync(
new StartScavengeReq {
Options = new StartScavengeReq.Types.Options {
ThreadCount = threadCount,
StartFromChunk = startFromChunk
}
},
EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials,
cancellationToken));

return result.ScavengeResult switch {
ScavengeResp.Types.ScavengeResult.Started => DatabaseScavengeResult.Started(result.ScavengeId),
Expand All @@ -54,7 +58,8 @@ public async Task<DatabaseScavengeResult> StopScavengeAsync(
string scavengeId,
UserCredentials? userCredentials = null,
CancellationToken cancellationToken = default) {
var result = await _client.StopScavengeAsync(new StopScavengeReq {
var result = await new Operations.Operations.OperationsClient(
await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).StopScavengeAsync(new StopScavengeReq {
Options = new StopScavengeReq.Types.Options {
ScavengeId = scavengeId
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public partial class EventStoreOperationsClient : EventStoreClientBase {
.FirstOrDefault(x => x.Key == Constants.Exceptions.ScavengeId)?.Value)
};

private readonly Operations.Operations.OperationsClient _client;
private readonly ILogger _log;

/// <summary>
Expand All @@ -33,7 +32,6 @@ public EventStoreOperationsClient(IOptions<EventStoreClientSettings> options) :
/// </summary>
/// <param name="settings"></param>
public EventStoreOperationsClient(EventStoreClientSettings? settings = null) : base(settings, ExceptionMap) {
_client = new Operations.Operations.OperationsClient(CallInvoker);
_log = Settings.LoggerFactory?.CreateLogger<EventStoreOperationsClient>() ??
new NullLogger<EventStoreOperationsClient>();
}
Expand Down
Loading