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

.NET 4.8 Framework support #267

Merged
merged 43 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1fb695f
WIP for .NET 4.8 support
alexeyzimarev Oct 10, 2023
af9944c
Make it build
alexeyzimarev Oct 11, 2023
cfb07e9
* trying to add dotnet 4.8 to ci
RagingKore Oct 17, 2023
6413ebe
* lets gooo
RagingKore Oct 17, 2023
46e3b0e
is 4.8 already on latest windows?
RagingKore Oct 17, 2023
830a438
more fixes to test
RagingKore Oct 17, 2023
bd50c68
could it be net48 instead?
RagingKore Oct 17, 2023
9a8b509
using windows-2019 runner
RagingKore Oct 17, 2023
0cdfa90
interesting...
RagingKore Oct 17, 2023
23144a0
single test step now
RagingKore Oct 17, 2023
45afde5
trying to figure out some stuff here with multiple windows runners
RagingKore Oct 17, 2023
10d6660
changed the order of the docker pull step
RagingKore Oct 17, 2023
fa41ba1
minor attempt to simplify matrices
RagingKore Oct 17, 2023
8adc099
nop
RagingKore Oct 17, 2023
4b9e3e1
it seems net48 can run on ubuntu with mono
RagingKore Oct 17, 2023
a87385f
install mono ai ai ai
RagingKore Oct 17, 2023
bb1dfed
added the same to the build samples step
RagingKore Oct 17, 2023
071a832
sudo?
RagingKore Oct 17, 2023
e8ce300
already has latest mongo
RagingKore Oct 17, 2023
26869d9
reference .net reference assemblies to enable mono compile on linux
thefringeninja Oct 17, 2023
670c60e
upgraded serilog packages
RagingKore Nov 6, 2023
1e086eb
sync with master
w1am Jan 11, 2024
9fb6be3
Remove errors
w1am Jan 12, 2024
bbfcad9
Fix more errors
w1am Jan 15, 2024
5f6e03b
Remove duplicates in solution
w1am Jan 15, 2024
0df0e7e
Remove duplicates
w1am Jan 15, 2024
e624b94
Fix compile errors
w1am Jan 17, 2024
b2dd065
initial commit
w1am Jan 18, 2024
c6db004
Remove redudant shims
w1am Jan 18, 2024
9c8b6ce
Sauces
w1am Jan 18, 2024
64610d0
add Microsoft.Extensions.Configuration.EnvironmentVariables
w1am Jan 18, 2024
0176cb8
Merge branch 'net48' into dev-70-net-framework-support
w1am Jan 18, 2024
85efe11
Fixes
w1am Jan 18, 2024
dde1fa0
Integrate the recommendations provided by Sergio
w1am Jan 19, 2024
d89a083
Try using HttpHandler
w1am Jan 23, 2024
4e8ca3a
Make use of EventStoreClientSettings.CreateHttpMessageHandler in Chan…
josephcummings Jan 23, 2024
5504336
Cleanup
josephcummings Jan 23, 2024
50d1c5b
Update ChannelFactory, handle null settings.CreateHttpMessageHandler
josephcummings Jan 23, 2024
5dbe63e
Explcitly map WinHttpHandler error messages during subscription handling
w1am Jan 25, 2024
798d083
Fix unnecessary break and improve WinHttpHandler comment
w1am Jan 25, 2024
fbc1fe6
Increase timeout and reconnect delay in subscription test
w1am Jan 25, 2024
de28e9d
Improve comment
w1am Jan 26, 2024
ec9b00c
Rm usage of redundant db config option 'ENABLE_EXTERNAL_TCP' breaking CI
josephcummings Jan 29, 2024
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
7 changes: 6 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net48;net6.0;net7.0;net8.0</TargetFrameworks>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Nullable>enable</Nullable>
<NullableContextOptions>enable</NullableContextOptions>
Expand All @@ -16,4 +16,9 @@
<GrpcPackageVersion>2.59.0</GrpcPackageVersion>
<GrpcToolsPackageVersion>2.59.0</GrpcToolsPackageVersion>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net48'">
<Reference Include="System.Net.Http"/>
<Reference Include="System.Web"/>
</ItemGroup>
</Project>
14 changes: 7 additions & 7 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))"/>
<PropertyGroup>
<RootNamespace>EventStore.Client</RootNamespace>
</PropertyGroup>
Expand All @@ -12,8 +12,8 @@
</PropertyGroup>

<ItemGroup Condition="$(MSBuildProjectName) != 'EventStore.Client'">
<ProjectReference Include="..\EventStore.Client\EventStore.Client.csproj" />
<Protobuf Access="internal" Include="$(ESProtoPath)" GrpcServices="Client" Link="protos/$(ESProto)" />
<ProjectReference Include="..\EventStore.Client\EventStore.Client.csproj"/>
<Protobuf Access="internal" Include="$(ESProtoPath)" GrpcServices="Client" Link="protos/$(ESProto)"/>
</ItemGroup>

<PropertyGroup>
Expand All @@ -30,8 +30,8 @@
</PropertyGroup>

<ItemGroup>
<None Include="..\..\LICENSE.md" Pack="true" PackagePath="\" />
<None Include="..\..\ouro.png" Pack="true" PackagePath="\" />
<None Include="..\..\LICENSE.md" Pack="true" PackagePath="\"/>
<None Include="..\..\ouro.png" Pack="true" PackagePath="\"/>
</ItemGroup>

<ItemGroup>
Expand All @@ -43,11 +43,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="MinVer" Version="3.0.0" PrivateAssets="All" />
<PackageReference Include="MinVer" Version="3.0.0" PrivateAssets="All"/>
</ItemGroup>

<ItemGroup>
<Compile Include="../EventStore.Client.Common/**/*.cs" Link="Common\%(RecursiveDir)/%(FileName)%(Extension)" />
<Compile Include="../EventStore.Client.Common/**/*.cs" Link="Common\%(RecursiveDir)/%(FileName)%(Extension)"/>
</ItemGroup>

<ItemGroup>
Expand Down
16 changes: 16 additions & 0 deletions src/EventStore.Client.Common/EpochExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
namespace EventStore.Client;

static class EpochExtensions {
#if NET
static readonly DateTime UnixEpoch = DateTime.UnixEpoch;
#else
const long TicksPerMillisecond = 10000;
const long TicksPerSecond = TicksPerMillisecond * 1000;
const long TicksPerMinute = TicksPerSecond * 60;
const long TicksPerHour = TicksPerMinute * 60;
const long TicksPerDay = TicksPerHour * 24;
const int DaysPerYear = 365;
const int DaysPer4Years = DaysPerYear * 4 + 1;
const int DaysPer100Years = DaysPer4Years * 25 - 1;
const int DaysPer400Years = DaysPer100Years * 4 + 1;
const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear;
const long UnixEpochTicks = DaysTo1970 * TicksPerDay;

static readonly DateTime UnixEpoch = new(UnixEpochTicks, DateTimeKind.Utc);
#endif

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

Expand Down
131 changes: 131 additions & 0 deletions src/EventStore.Client.Common/Shims/Index.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#if !NET
using System.Runtime.CompilerServices;

namespace System;

/// <summary>Represent a type can be used to index a collection either from the start or the end.</summary>
/// <remarks>
/// Index is used by the C# compiler to support the new index syntax
/// <code>
/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ;
/// int lastElement = someArray[^1]; // lastElement = 5
/// </code>
/// </remarks>
internal readonly struct Index : IEquatable<Index>
{
private readonly int _value;

/// <summary>Construct an Index using a value and indicating if the index is from the start or from the end.</summary>
/// <param name="value">The index value. it has to be zero or positive number.</param>
/// <param name="fromEnd">Indicating if the index is from the start or from the end.</param>
/// <remarks>
/// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Index(int value, bool fromEnd = false)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
}

if (fromEnd)
_value = ~value;
else
_value = value;
}

// The following private constructors mainly created for perf reason to avoid the checks
private Index(int value)
{
_value = value;
}

/// <summary>Create an Index pointing at first element.</summary>
public static Index Start => new Index(0);

/// <summary>Create an Index pointing at beyond last element.</summary>
public static Index End => new Index(~0);

/// <summary>Create an Index from the start at the position indicated by the value.</summary>
/// <param name="value">The index value from the start.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Index FromStart(int value)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
}

return new Index(value);
}

/// <summary>Create an Index from the end at the position indicated by the value.</summary>
/// <param name="value">The index value from the end.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Index FromEnd(int value)
{
if (value < 0)
{
throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative");
}

return new Index(~value);
}

/// <summary>Returns the index value.</summary>
public int Value
{
get
{
if (_value < 0)
return ~_value;
else
return _value;
}
}

/// <summary>Indicates whether the index is from the start or the end.</summary>
public bool IsFromEnd => _value < 0;

/// <summary>Calculate the offset from the start using the giving collection length.</summary>
/// <param name="length">The length of the collection that the Index will be used with. length has to be a positive value</param>
/// <remarks>
/// For performance reason, we don't validate the input length parameter and the returned offset value against negative values.
/// we don't validate either the returned offset is greater than the input length.
/// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and
/// then used to index a collection will get out of range exception which will be same affect as the validation.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetOffset(int length)
{
int offset = _value;
if (IsFromEnd)
{
// offset = length - (~value)
// offset = length + (~(~value) + 1)
// offset = length + value + 1

offset += length + 1;
}
return offset;
}

/// <summary>Indicates whether the current Index object is equal to another object of the same type.</summary>
/// <param name="value">An object to compare with this object</param>
public override bool Equals(object? value) => value is Index && _value == ((Index)value)._value;

/// <summary>Indicates whether the current Index object is equal to another Index object.</summary>
/// <param name="other">An object to compare with this object</param>
public bool Equals(Index other) => _value == other._value;

/// <summary>Returns the hash code for this instance.</summary>
public override int GetHashCode() => _value;

/// <summary>Converts integer number to an Index.</summary>
public static implicit operator Index(int value) => FromStart(value);

/// <summary>Converts the value of the current Index object to its equivalent string representation.</summary>
public override string ToString() => IsFromEnd ? $"^{((uint)Value)}" : ((uint)Value).ToString();
}
#endif
9 changes: 9 additions & 0 deletions src/EventStore.Client.Common/Shims/IsExternalInit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#if !NET
using System.ComponentModel;

// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices;

[EditorBrowsable(EditorBrowsableState.Never)]
internal class IsExternalInit{}
#endif
79 changes: 79 additions & 0 deletions src/EventStore.Client.Common/Shims/Range.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#if !NET
using System.Runtime.CompilerServices;

namespace System;

/// <summary>Represent a range has start and end indexes.</summary>
/// <remarks>
/// Range is used by the C# compiler to support the range syntax.
/// <code>
/// int[] someArray = new int[5] { 1, 2, 3, 4, 5 };
/// int[] subArray1 = someArray[0..2]; // { 1, 2 }
/// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 }
/// </code>
/// </remarks>
internal readonly struct Range : IEquatable<Range>
{
/// <summary>Represent the inclusive start index of the Range.</summary>
public Index Start { get; }

/// <summary>Represent the exclusive end index of the Range.</summary>
public Index End { get; }

/// <summary>Construct a Range object using the start and end indexes.</summary>
/// <param name="start">Represent the inclusive start index of the range.</param>
/// <param name="end">Represent the exclusive end index of the range.</param>
public Range(Index start, Index end)
{
Start = start;
End = end;
}

/// <summary>Indicates whether the current Range object is equal to another object of the same type.</summary>
/// <param name="value">An object to compare with this object</param>
public override bool Equals(object? value) =>
value is Range r &&
r.Start.Equals(Start) &&
r.End.Equals(End);

/// <summary>Indicates whether the current Range object is equal to another Range object.</summary>
/// <param name="other">An object to compare with this object</param>
public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End);

/// <summary>Returns the hash code for this instance.</summary>
public override int GetHashCode() => Start.GetHashCode() * 31 + End.GetHashCode();

/// <summary>Converts the value of the current Range object to its equivalent string representation.</summary>
public override string ToString() => $"{Start}..{End}";

/// <summary>Create a Range object starting from start index to the end of the collection.</summary>
public static Range StartAt(Index start) => new(start, Index.End);

/// <summary>Create a Range object starting from first element in the collection to the end Index.</summary>
public static Range EndAt(Index end) => new(Index.Start, end);

/// <summary>Create a Range object starting from first element to the end.</summary>
public static Range All => new(Index.Start, Index.End);

/// <summary>Calculate the start offset and length of range object using a collection length.</summary>
/// <param name="length">The length of the collection that the range will be used with. length has to be a positive value.</param>
/// <remarks>
/// For performance reason, we don't validate the input length parameter against negative values.
/// It is expected Range will be used with collections which always have non negative length/count.
/// We validate the range is inside the length scope though.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public (int Offset, int Length) GetOffsetAndLength(int length)
{
int start = Start.GetOffset(length);
int end = End.GetOffset(length);

if ((uint)end > (uint)length || (uint)start > (uint)end)
{
throw new ArgumentOutOfRangeException(nameof(length));
}

return (start, end - start);
}
}
#endif
8 changes: 8 additions & 0 deletions src/EventStore.Client.Common/Shims/TaskCompletionSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#if !NET
namespace System.Threading.Tasks;

internal class TaskCompletionSource : TaskCompletionSource<object?> {
public void SetResult() => base.SetResult(null);
public bool TrySetResult() => base.TrySetResult(null);
}
#endif
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>The GRPC client API for Event Store Operations, e.g., Scavenging. Get the open source or commercial versions of Event Store server from https://eventstore.com/</Description>
</PropertyGroup>
<PropertyGroup>
<Description>The GRPC client API for Event Store Operations, e.g., Scavenging. Get the open source or commercial versions of Event Store server from https://eventstore.com/</Description>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>The GRPC client API for Event Store Persistent Subscriptions. Get the open source or commercial versions of Event Store server from https://eventstore.com/</Description>
</PropertyGroup>
<PropertyGroup>
<Description>The GRPC client API for Event Store Persistent Subscriptions. Get the open source or commercial versions of Event Store server from https://eventstore.com/</Description>
</PropertyGroup>
<ItemGroup>
<InternalsVisibleTo Include="EventStore.Client.PersistentSubscriptions.Tests"/>
</ItemGroup>
</Project>
Loading
Loading