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

Support for .NET Standard 2.0 and 2.1 #513

Merged
merged 49 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
850348c
Support for .NET Standard 2.0 and 2.1
mtmk Jun 10, 2024
3b7c839
Merge remote-tracking branch 'refs/remotes/origin/main' into netstand…
mtmk Jun 13, 2024
c4c1994
merge fix
mtmk Jun 13, 2024
b1d53c9
Auth error fix
mtmk Jun 13, 2024
b190aae
dotnet format
mtmk Jun 13, 2024
1560f40
dotnet format
mtmk Jun 13, 2024
dca0c0e
standardize test utils
mtmk Jun 13, 2024
c61d0c3
standardize JetStream
mtmk Jun 13, 2024
117fe37
dotnet format
mtmk Jun 13, 2024
fcdec62
standardize KV
mtmk Jun 13, 2024
4c8cae6
standardize JetStream tweaks
mtmk Jun 13, 2024
c501259
standardize object store
mtmk Jun 13, 2024
76c3bc7
standardize services
mtmk Jun 13, 2024
42e8255
standardize extensions
mtmk Jun 13, 2024
91ffcda
fixed code for failing tests
mtmk Jun 13, 2024
2013c0a
dotnet format
mtmk Jun 13, 2024
99c05c8
framework core tests
mtmk Jun 13, 2024
055d693
test fix
mtmk Jun 13, 2024
abc6b02
other tests
mtmk Jun 13, 2024
f6b55ee
revert net481 tests
mtmk Jun 13, 2024
3168197
use read loop
mtmk Jun 13, 2024
123514f
tidy-up
mtmk Jun 13, 2024
4dbcd84
platform tests
mtmk Jun 13, 2024
b206685
windows test tweak
mtmk Jun 13, 2024
83f02c5
dotnet format
mtmk Jun 13, 2024
5516b20
platform basic tests
mtmk Jun 14, 2024
2cee902
revert unnecessary changes to test utils
mtmk Jun 14, 2024
8cf5f8a
netstandard ulong interlocked increment
mtmk Jun 14, 2024
2314492
channel reader extension tidy-up
mtmk Jun 14, 2024
dec2a26
simplify diffs
mtmk Jun 14, 2024
b53cd08
simplify diffs
mtmk Jun 14, 2024
6e6db0c
simplify diffs
mtmk Jun 14, 2024
5cebd56
use Nullable package
mtmk Jun 14, 2024
6dd35d6
simplify
mtmk Jun 14, 2024
0ce7c80
use Nullable package
mtmk Jun 14, 2024
cf213e6
simplify
mtmk Jun 14, 2024
1d2166a
simplify diffs
mtmk Jun 14, 2024
e0c282f
global using
mtmk Jun 14, 2024
2ea8828
use Nullable package for DoesNotReturn
mtmk Jun 14, 2024
4b5a94c
dotnet format
mtmk Jun 14, 2024
c56cc54
use NETSTANDARD in defs
mtmk Jun 14, 2024
7bf683b
IsNotCompletedSuccessfully extension
mtmk Jun 17, 2024
74b3b9c
first span extension
mtmk Jun 17, 2024
9695a1d
use span-char toString
mtmk Jun 17, 2024
695bc6e
KV base64 exception handling
mtmk Jun 17, 2024
bc2aadc
dotnet format
mtmk Jun 18, 2024
ebce217
guarding MemoryMarshal.TryGetArray
mtmk Jun 18, 2024
6641414
adjusted dictionary remove call
mtmk Jun 18, 2024
fb24f7f
Merge branch 'refs/heads/main' into netstandard-support
mtmk Jun 20, 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
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,7 @@ jobs:

- name: Memory Test (net6.0)
run: dotMemoryUnit $env:userprofile\.dotnet\tools\nunit.exe --propagate-exit-code -- .\tests\NATS.Client.Core.MemoryTests\bin\Release\net6.0\NATS.Client.Core.MemoryTests.dll

- name: Platform Test (Windows net481)
run: dotnet test -c Release --no-build --logger:"console;verbosity=normal" -f net481 .\tests\NATS.Client.Platform.Windows.Tests\NATS.Client.Platform.Windows.Tests.csproj

7 changes: 7 additions & 0 deletions NATS.Client.sln
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.OpenTelemetry", "sa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NATS.Net.OpenTelemetry.Tests", "tests\NATS.Net.OpenTelemetry.Tests\NATS.Net.OpenTelemetry.Tests.csproj", "{B8554582-DE19-41A2-9784-9B27C9F22429}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NATS.Client.Platform.Windows.Tests", "tests\NATS.Client.Platform.Windows.Tests\NATS.Client.Platform.Windows.Tests.csproj", "{A37994CC-A23A-415E-8B61-9468C7178A55}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -285,6 +287,10 @@ Global
{B8554582-DE19-41A2-9784-9B27C9F22429}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8554582-DE19-41A2-9784-9B27C9F22429}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8554582-DE19-41A2-9784-9B27C9F22429}.Release|Any CPU.Build.0 = Release|Any CPU
{A37994CC-A23A-415E-8B61-9468C7178A55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A37994CC-A23A-415E-8B61-9468C7178A55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A37994CC-A23A-415E-8B61-9468C7178A55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A37994CC-A23A-415E-8B61-9468C7178A55}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -334,6 +340,7 @@ Global
{2EA0EB68-1AA4-40AC-8FA2-B51532075567} = {4827B3EC-73D8-436D-AE2A-5E29AC95FD0C}
{474BA453-9CFF-41C2-B2E7-ADD92CC93E86} = {95A69671-16CA-4133-981C-CC381B7AAA30}
{B8554582-DE19-41A2-9784-9B27C9F22429} = {C526E8AB-739A-48D7-8FC4-048978C9B650}
{A37994CC-A23A-415E-8B61-9468C7178A55} = {C526E8AB-739A-48D7-8FC4-048978C9B650}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8CBB7278-D093-448E-B3DE-B5991209A1AA}
Expand Down
99 changes: 87 additions & 12 deletions src/NATS.Client.Core/Commands/CommandWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ public async Task CancelReaderLoopAsync()

if (cts != null)
{
#if NET6_0
cts.Cancel();
#else
#if NET8_0_OR_GREATER
await cts.CancelAsync().ConfigureAwait(false);
#else
cts.Cancel();
#endif
}

Expand All @@ -133,10 +133,10 @@ public async ValueTask DisposeAsync()

_disposed = true;

#if NET6_0
_cts.Cancel();
#else
#if NET8_0_OR_GREATER
await _cts.CancelAsync().ConfigureAwait(false);
#else
_cts.Cancel();
#endif

_channelLock.Writer.TryComplete();
Expand Down Expand Up @@ -164,7 +164,11 @@ public ValueTask ConnectAsync(ClientOpts connectOpts, CancellationToken cancella
return ConnectStateMachineAsync(false, connectOpts, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stupid question: would it be cleaner to put the logic shifts in IsNotCompletedSuccessfully() extension method and just aggressive inline? Or would it be too ugly for how shims should be composed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes good point, fewer #if the better!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

{
return ConnectStateMachineAsync(true, connectOpts, cancellationToken);
}
Expand All @@ -184,7 +188,7 @@ public ValueTask ConnectAsync(ClientOpts connectOpts, CancellationToken cancella
_semLock.Release();
}

return ValueTask.CompletedTask;
return default;
}

public ValueTask PingAsync(PingCommand pingCommand, CancellationToken cancellationToken)
Expand All @@ -198,7 +202,11 @@ public ValueTask PingAsync(PingCommand pingCommand, CancellationToken cancellati
return PingStateMachineAsync(false, pingCommand, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
{
return PingStateMachineAsync(true, pingCommand, cancellationToken);
}
Expand All @@ -219,7 +227,7 @@ public ValueTask PingAsync(PingCommand pingCommand, CancellationToken cancellati
_semLock.Release();
}

return ValueTask.CompletedTask;
return default;
}

public ValueTask PongAsync(CancellationToken cancellationToken = default)
Expand All @@ -233,7 +241,11 @@ public ValueTask PongAsync(CancellationToken cancellationToken = default)
return PongStateMachineAsync(false, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
{
return PongStateMachineAsync(true, cancellationToken);
}
Expand All @@ -253,7 +265,7 @@ public ValueTask PongAsync(CancellationToken cancellationToken = default)
_semLock.Release();
}

return ValueTask.CompletedTask;
return default;
}

public ValueTask PublishAsync<T>(string subject, T? value, NatsHeaders? headers, string? replyTo, INatsSerialize<T> serializer, CancellationToken cancellationToken)
Expand Down Expand Up @@ -306,7 +318,11 @@ public ValueTask PublishAsync<T>(string subject, T? value, NatsHeaders? headers,
return PublishStateMachineAsync(false, subject, replyTo, headersBuffer, payloadBuffer, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
{
return PublishStateMachineAsync(true, subject, replyTo, headersBuffer, payloadBuffer, cancellationToken);
}
Expand Down Expand Up @@ -335,7 +351,7 @@ public ValueTask PublishAsync<T>(string subject, T? value, NatsHeaders? headers,
}
}

return ValueTask.CompletedTask;
return default;
}

public ValueTask SubscribeAsync(int sid, string subject, string? queueGroup, int? maxMsgs, CancellationToken cancellationToken)
Expand All @@ -349,7 +365,11 @@ public ValueTask SubscribeAsync(int sid, string subject, string? queueGroup, int
return SubscribeStateMachineAsync(false, sid, subject, queueGroup, maxMsgs, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
{
return SubscribeStateMachineAsync(true, sid, subject, queueGroup, maxMsgs, cancellationToken);
}
Expand All @@ -369,7 +389,7 @@ public ValueTask SubscribeAsync(int sid, string subject, string? queueGroup, int
_semLock.Release();
}

return ValueTask.CompletedTask;
return default;
}

public ValueTask UnsubscribeAsync(int sid, int? maxMsgs, CancellationToken cancellationToken)
Expand All @@ -383,7 +403,11 @@ public ValueTask UnsubscribeAsync(int sid, int? maxMsgs, CancellationToken cance
return UnsubscribeStateMachineAsync(false, sid, maxMsgs, cancellationToken);
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
#else
if (_flushTask is { IsCompletedSuccessfully: false })
#endif
{
return UnsubscribeStateMachineAsync(true, sid, maxMsgs, cancellationToken);
}
Expand All @@ -403,7 +427,7 @@ public ValueTask UnsubscribeAsync(int sid, int? maxMsgs, CancellationToken cance
_semLock.Release();
}

return ValueTask.CompletedTask;
return default;
}

// only used for internal testing
Expand All @@ -413,10 +437,17 @@ internal async Task TestStallFlushAsync(TimeSpan timeSpan, CancellationToken can

try
{
#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.ConfigureAwait(false);
}
#endif

_flushTask = Task.Delay(timeSpan, cancellationToken);
}
Expand Down Expand Up @@ -630,10 +661,17 @@ private async ValueTask ConnectStateMachineAsync(bool lockHeld, ClientOpts conne
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WriteConnect(_pipeWriter, connectOpts);
EnqueueCommand();
Expand Down Expand Up @@ -667,10 +705,17 @@ private async ValueTask PingStateMachineAsync(bool lockHeld, PingCommand pingCom
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WritePing(_pipeWriter);
_enqueuePing(pingCommand);
Expand Down Expand Up @@ -705,10 +750,17 @@ private async ValueTask PongStateMachineAsync(bool lockHeld, CancellationToken c
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WritePong(_pipeWriter);
EnqueueCommand();
Expand All @@ -725,7 +777,9 @@ private async ValueTask PongStateMachineAsync(bool lockHeld, CancellationToken c
}
}

#if !NETSTANDARD
[AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder))]
#endif
private async ValueTask PublishStateMachineAsync(bool lockHeld, string subject, string? replyTo, NatsPooledBufferWriter<byte>? headersBuffer, NatsPooledBufferWriter<byte> payloadBuffer, CancellationToken cancellationToken)
{
try
Expand All @@ -745,10 +799,17 @@ private async ValueTask PublishStateMachineAsync(bool lockHeld, string subject,
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WritePublish(_pipeWriter, subject, replyTo, headersBuffer?.WrittenMemory, payloadBuffer.WrittenMemory);
EnqueueCommand();
Expand Down Expand Up @@ -794,10 +855,17 @@ private async ValueTask SubscribeStateMachineAsync(bool lockHeld, int sid, strin
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WriteSubscribe(_pipeWriter, sid, subject, queueGroup, maxMsgs);
EnqueueCommand();
Expand Down Expand Up @@ -831,10 +899,17 @@ private async ValueTask UnsubscribeStateMachineAsync(bool lockHeld, int sid, int
throw new ObjectDisposedException(nameof(CommandWriter));
}

#if NETSTANDARD2_0
if (_flushTask.IsNotCompletedSuccessfully())
{
await _flushTask!.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#else
if (_flushTask is { IsCompletedSuccessfully: false })
{
await _flushTask.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false);
}
#endif

_protocolWriter.WriteUnsubscribe(_pipeWriter, sid, maxMsgs);
EnqueueCommand();
Expand Down
2 changes: 2 additions & 0 deletions src/NATS.Client.Core/Commands/NatsPooledBufferWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ private void ResizeBuffer(int sizeHint)
{
var minimumSize = (uint)_index + (uint)sizeHint;

#if !NETSTANDARD
// The ArrayPool<T> class has a maximum threshold of 1024 * 1024 for the maximum length of
// pooled arrays, and once this is exceeded it will just allocate a new array every time
// of exactly the requested size. In that case, we manually round up the requested size to
Expand All @@ -202,6 +203,7 @@ private void ResizeBuffer(int sizeHint)
{
minimumSize = BitOperations.RoundUpToPowerOf2(minimumSize);
}
#endif

_pool.Resize(ref _array, (int)minimumSize);
}
Expand Down
8 changes: 8 additions & 0 deletions src/NATS.Client.Core/INatsSerialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,11 @@ public void Serialize(IBufferWriter<byte> bufferWriter, T value)
return (T)(object)Encoding.UTF8.GetString(buffer);
}

#if NETSTANDARD2_0
var span = buffer.IsSingleSegment ? buffer.First.Span : buffer.ToArray();
#else
var span = buffer.IsSingleSegment ? buffer.FirstSpan : buffer.ToArray();
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another potential candidate for ext-method-consolidation is buffer.FirstSpan vs buffer.First.Span.

I should note that, AFAIR, if the extension method is internal, Resharper/Rider can always let team 're-dupe' the callsites later easily if ppl change their minds.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


if (typeof(T) == typeof(DateTime) || typeof(T) == typeof(DateTime?))
{
Expand Down Expand Up @@ -621,7 +625,11 @@ public void Serialize(IBufferWriter<byte> bufferWriter, T value)
{
if (readOnlySequence.IsSingleSegment)
{
#if NETSTANDARD2_0
bufferWriter.Write(readOnlySequence.First.Span);
#else
bufferWriter.Write(readOnlySequence.FirstSpan);
#endif
}
else
{
Expand Down
4 changes: 4 additions & 0 deletions src/NATS.Client.Core/Internal/ActivityEndingMsgReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ public override bool TryPeek(out NatsMsg<T> item)
return _inner.TryPeek(out item);
}

#if NETSTANDARD2_0
public async IAsyncEnumerable<NatsMsg<T>> ReadAllAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
#else
public override async IAsyncEnumerable<NatsMsg<T>> ReadAllAsync([EnumeratorCancellation] CancellationToken cancellationToken = default)
#endif
{
var handle = GCHandle.Alloc(_sub);
try
Expand Down
4 changes: 4 additions & 0 deletions src/NATS.Client.Core/Internal/BufferExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ public static ReadOnlySpan<byte> ToSpan(this ReadOnlySequence<byte> buffer)
{
if (buffer.IsSingleSegment)
{
#if NETSTANDARD2_0
return buffer.First.Span;
#else
return buffer.FirstSpan;
#endif
}

return buffer.ToArray();
Expand Down
Loading
Loading