Skip to content

Commit 3a3d40c

Browse files
committed
Remove more synchronous code
Part of the fix to #1472 * Remove `ISession.Transmit` * Change `HeartbeatWriteTimerCallback` to be `async` and use `WriteAsync` * Make `HeartbeatReadTimerCallback` async * Ensure toxiproxy is reset at the end of the test run. * Make frame / command dispatch async * Make a couple more methods async * Update Makefile * Do not release a SemaphoreSlim that is about to be disposed. * Fix toxiproxy duplicated entity for good, hopefully * Add two missing `.ConfigureAwait(false)` calls * Add missing `.ConfigureAwait(false)` call
1 parent 9bf0e5c commit 3a3d40c

File tree

14 files changed

+129
-145
lines changed

14 files changed

+129
-145
lines changed

.ci/ubuntu/gha-setup.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function start_toxiproxy
4040
{
4141
if [[ $run_toxiproxy == 'true' ]]
4242
then
43-
sudo ss -4nlp
43+
# sudo ss -4nlp
4444
echo "[INFO] starting Toxiproxy server docker container"
4545
docker rm --force "$toxiproxy_docker_name" 2>/dev/null || echo "[INFO] $toxiproxy_docker_name was not running"
4646
docker run --pull always --detach \

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ build:
88

99
test:
1010
dotnet test $(CURDIR)/projects/Test/Unit/Unit.csproj --logger 'console;verbosity=detailed'
11-
dotnet test --environment "RABBITMQ_RABBITMQCTL_PATH=DOCKER:$$(docker inspect --format='{{.Id}}' $(RABBITMQ_DOCKER_NAME))" $(CURDIR)/projects/Test/Integration/Integration.csproj --logger 'console;verbosity=detailed'
11+
dotnet test --environment "RABBITMQ_RABBITMQCTL_PATH=DOCKER:$$(docker inspect --format='{{.Id}}' $(RABBITMQ_DOCKER_NAME))" \
12+
--environment 'RABBITMQ_LONG_RUNNING_TESTS=true' $(CURDIR)/projects/Test/Integration/Integration.csproj --logger 'console;verbosity=detailed'
13+
--environment 'RABBITMQ_TOXIPROXY_TESTS=true' \
14+
--environment 'PASSWORD=grapefruit' \
15+
--environment SSL_CERTS_DIR="$(CURDIR)/.ci/certs" \
16+
"$(CURDIR)/projects/Test/Integration/Integration.csproj" --logger 'console;verbosity=detailed'
1217
dotnet test --environment "RABBITMQ_RABBITMQCTL_PATH=DOCKER:$$(docker inspect --format='{{.Id}}' $(RABBITMQ_DOCKER_NAME))" $(CURDIR)/projects/Test/SequentialIntegration/SequentialIntegration.csproj --logger 'console;verbosity=detailed'
1318

1419
# Note:

projects/RabbitMQ.Client/FrameworkExtension/DictionaryExtension.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,35 @@
1-
using System.Collections.Generic;
1+
// This source code is dual-licensed under the Apache License, version
2+
// 2.0, and the Mozilla Public License, version 2.0.
3+
//
4+
// The APL v2.0:
5+
//
6+
//---------------------------------------------------------------------------
7+
// Copyright (c) 2007-2020 VMware, Inc.
8+
//
9+
// Licensed under the Apache License, Version 2.0 (the "License");
10+
// you may not use this file except in compliance with the License.
11+
// You may obtain a copy of the License at
12+
//
13+
// https://www.apache.org/licenses/LICENSE-2.0
14+
//
15+
// Unless required by applicable law or agreed to in writing, software
16+
// distributed under the License is distributed on an "AS IS" BASIS,
17+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
// See the License for the specific language governing permissions and
19+
// limitations under the License.
20+
//---------------------------------------------------------------------------
21+
//
22+
// The MPL v2.0:
23+
//
24+
//---------------------------------------------------------------------------
25+
// This Source Code Form is subject to the terms of the Mozilla Public
26+
// License, v. 2.0. If a copy of the MPL was not distributed with this
27+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
28+
//
29+
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
30+
//---------------------------------------------------------------------------
31+
32+
using System.Collections.Generic;
233

334
namespace RabbitMQ
435
{

projects/RabbitMQ.Client/client/framing/Channel.cs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,22 @@ public override Task _Private_ChannelCloseOkAsync(CancellationToken cancellation
5454
return ModelSendAsync(method, cancellationToken).AsTask();
5555
}
5656

57-
public override void _Private_ChannelFlowOk(bool active)
57+
public override Task _Private_ChannelFlowOkAsync(bool active, CancellationToken cancellationToken)
5858
{
59-
ChannelSend(new ChannelFlowOk(active));
59+
var method = new ChannelFlowOk(active);
60+
return ModelSendAsync(method, cancellationToken).AsTask();
6061
}
6162

62-
public override void _Private_ConnectionCloseOk()
63+
public override Task _Private_ConnectionCloseOkAsync(CancellationToken cancellationToken)
6364
{
64-
ChannelSend(new ConnectionCloseOk());
65+
var method = new ConnectionCloseOk();
66+
return ModelSendAsync(method, cancellationToken).AsTask();
6567
}
6668

6769
public override ValueTask BasicAckAsync(ulong deliveryTag, bool multiple)
6870
{
6971
var method = new BasicAck(deliveryTag, multiple);
70-
// TODO cancellation token?
72+
// TODO use cancellation token
7173
return ModelSendAsync(method, CancellationToken.None);
7274
}
7375

@@ -85,101 +87,103 @@ public override Task BasicRejectAsync(ulong deliveryTag, bool requeue)
8587
return ModelSendAsync(method, CancellationToken.None).AsTask();
8688
}
8789

88-
protected override bool DispatchAsynchronous(in IncomingCommand cmd)
90+
protected override Task<bool> DispatchCommandAsync(IncomingCommand cmd, CancellationToken cancellationToken)
8991
{
9092
switch (cmd.CommandId)
9193
{
9294
case ProtocolCommandId.BasicDeliver:
9395
{
9496
HandleBasicDeliver(in cmd);
95-
return true;
97+
return Task.FromResult(true);
9698
}
9799
case ProtocolCommandId.BasicAck:
98100
{
99101
HandleBasicAck(in cmd);
100-
return true;
102+
return Task.FromResult(true);
101103
}
102104
case ProtocolCommandId.BasicCancel:
103105
{
104106
HandleBasicCancel(in cmd);
105-
return true;
107+
return Task.FromResult(true);
106108
}
107109
case ProtocolCommandId.BasicCancelOk:
108110
{
109-
return HandleBasicCancelOk(in cmd);
111+
bool result = HandleBasicCancelOk(in cmd);
112+
return Task.FromResult(result);
110113
}
111114
case ProtocolCommandId.BasicConsumeOk:
112115
{
113-
return HandleBasicConsumeOk(in cmd);
116+
bool result = HandleBasicConsumeOk(in cmd);
117+
return Task.FromResult(result);
114118
}
115119
case ProtocolCommandId.BasicGetEmpty:
116120
{
117-
return HandleBasicGetEmpty(in cmd);
121+
bool result = HandleBasicGetEmpty(in cmd);
122+
return Task.FromResult(result);
118123
}
119124
case ProtocolCommandId.BasicGetOk:
120125
{
121-
return HandleBasicGetOk(in cmd);
126+
bool result = HandleBasicGetOk(in cmd);
127+
return Task.FromResult(result);
122128
}
123129
case ProtocolCommandId.BasicNack:
124130
{
125131
HandleBasicNack(in cmd);
126-
return true;
132+
return Task.FromResult(true);
127133
}
128134
case ProtocolCommandId.BasicReturn:
129135
{
130136
HandleBasicReturn(in cmd);
131-
return true;
137+
return Task.FromResult(true);
132138
}
133139
case ProtocolCommandId.ChannelClose:
134140
{
135-
HandleChannelClose(in cmd);
136-
return true;
141+
return HandleChannelCloseAsync(cmd, cancellationToken);
137142
}
138143
case ProtocolCommandId.ChannelCloseOk:
139144
{
140145
HandleChannelCloseOk(in cmd);
141-
return true;
146+
return Task.FromResult(true);
142147
}
143148
case ProtocolCommandId.ChannelFlow:
144149
{
145-
HandleChannelFlow(in cmd);
146-
return true;
150+
return HandleChannelFlowAsync(cmd, cancellationToken);
147151
}
148152
case ProtocolCommandId.ConnectionBlocked:
149153
{
150154
HandleConnectionBlocked(in cmd);
151-
return true;
155+
return Task.FromResult(true);
152156
}
153157
case ProtocolCommandId.ConnectionClose:
154158
{
155-
HandleConnectionClose(in cmd);
156-
return true;
159+
return HandleConnectionCloseAsync(cmd, cancellationToken);
157160
}
158161
case ProtocolCommandId.ConnectionSecure:
159162
{
160163
HandleConnectionSecure(in cmd);
161-
return true;
164+
return Task.FromResult(true);
162165
}
163166
case ProtocolCommandId.ConnectionStart:
164167
{
165168
HandleConnectionStart(in cmd);
166-
return true;
169+
return Task.FromResult(true);
167170
}
168171
case ProtocolCommandId.ConnectionTune:
169172
{
170173
HandleConnectionTune(in cmd);
171-
return true;
174+
return Task.FromResult(true);
172175
}
173176
case ProtocolCommandId.ConnectionUnblocked:
174177
{
175178
HandleConnectionUnblocked(in cmd);
176-
return true;
179+
return Task.FromResult(true);
177180
}
178181
case ProtocolCommandId.QueueDeclareOk:
179182
{
180-
return HandleQueueDeclareOk(in cmd);
183+
bool result = HandleQueueDeclareOk(in cmd);
184+
return Task.FromResult(result);
181185
}
182-
default: return false;
186+
default: return Task.FromResult(false);
183187
}
184188
}
185189
}

projects/RabbitMQ.Client/client/impl/ChannelBase.cs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ protected ChannelBase(ConnectionConfig config, ISession session)
9292
_flowControlWrapper = new EventingWrapper<FlowControlEventArgs>("OnFlowControl", onException);
9393
_channelShutdownWrapper = new EventingWrapper<ShutdownEventArgs>("OnChannelShutdown", onException);
9494
_recoveryWrapper = new EventingWrapper<EventArgs>("OnChannelRecovery", onException);
95-
session.CommandReceived = HandleCommand;
95+
session.CommandReceived = HandleCommandAsync;
9696
session.SessionShutdown += OnSessionShutdown;
9797
Session = session;
9898
}
@@ -344,7 +344,7 @@ await ModelSendAsync(method, k.CancellationToken)
344344
}
345345
}
346346

347-
protected abstract bool DispatchAsynchronous(in IncomingCommand cmd);
347+
protected abstract Task<bool> DispatchCommandAsync(IncomingCommand cmd, CancellationToken cancellationToken);
348348

349349
protected void Enqueue(IRpcContinuation k)
350350
{
@@ -393,22 +393,16 @@ internal void FinishClose()
393393
m_connectionStartCell?.TrySetResult(null);
394394
}
395395

396-
private void HandleCommand(in IncomingCommand cmd)
396+
private async Task HandleCommandAsync(IncomingCommand cmd, CancellationToken cancellationToken)
397397
{
398-
if (!DispatchAsynchronous(in cmd)) // Was asynchronous. Already processed. No need to process further.
398+
// Was asynchronous. Already processed. No need to process further.
399+
if (false == await DispatchCommandAsync(cmd, cancellationToken).ConfigureAwait(false))
399400
{
400401
IRpcContinuation c = _continuationQueue.Next();
401402
c.HandleCommand(in cmd);
402403
}
403404
}
404405

405-
// TODO REMOVE rabbitmq-dotnet-client-1472
406-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
407-
protected void ChannelSend<T>(in T method) where T : struct, IOutgoingAmqpMethod
408-
{
409-
Session.Transmit(in method);
410-
}
411-
412406
[MethodImpl(MethodImplOptions.AggressiveInlining)]
413407
protected ValueTask ModelSendAsync<T>(in T method, CancellationToken cancellationToken) where T : struct, IOutgoingAmqpMethod
414408
{
@@ -756,7 +750,7 @@ protected void HandleBasicReturn(in IncomingCommand cmd)
756750
}
757751
}
758752

759-
protected void HandleChannelClose(in IncomingCommand cmd)
753+
protected async Task<bool> HandleChannelCloseAsync(IncomingCommand cmd, CancellationToken cancellationToken)
760754
{
761755
try
762756
{
@@ -769,8 +763,9 @@ protected void HandleChannelClose(in IncomingCommand cmd)
769763

770764
Session.Close(CloseReason, false);
771765

772-
// TODO async
773-
_Private_ChannelCloseOkAsync(CancellationToken.None).EnsureCompleted();
766+
await _Private_ChannelCloseOkAsync(cancellationToken)
767+
.ConfigureAwait(false);
768+
return true;
774769
}
775770
finally
776771
{
@@ -801,11 +796,11 @@ protected void HandleChannelCloseOk(in IncomingCommand cmd)
801796
}
802797
}
803798

804-
protected void HandleChannelFlow(in IncomingCommand cmd)
799+
protected async Task<bool> HandleChannelFlowAsync(IncomingCommand cmd, CancellationToken cancellationToken)
805800
{
806801
try
807802
{
808-
var active = new ChannelFlow(cmd.MethodSpan)._active;
803+
bool active = new ChannelFlow(cmd.MethodSpan)._active;
809804
if (active)
810805
{
811806
_flowControlBlock.Set();
@@ -815,12 +810,15 @@ protected void HandleChannelFlow(in IncomingCommand cmd)
815810
_flowControlBlock.Reset();
816811
}
817812

818-
_Private_ChannelFlowOk(active);
813+
await _Private_ChannelFlowOkAsync(active, cancellationToken)
814+
.ConfigureAwait(false);
819815

820816
if (!_flowControlWrapper.IsEmpty)
821817
{
822818
_flowControlWrapper.Invoke(this, new FlowControlEventArgs(active));
823819
}
820+
821+
return true;
824822
}
825823
finally
826824
{
@@ -841,7 +839,7 @@ protected void HandleConnectionBlocked(in IncomingCommand cmd)
841839
}
842840
}
843841

844-
protected void HandleConnectionClose(in IncomingCommand cmd)
842+
protected async Task<bool> HandleConnectionCloseAsync(IncomingCommand cmd, CancellationToken cancellationToken)
845843
{
846844
try
847845
{
@@ -850,7 +848,8 @@ protected void HandleConnectionClose(in IncomingCommand cmd)
850848
try
851849
{
852850
Session.Connection.ClosedViaPeer(reason);
853-
_Private_ConnectionCloseOk();
851+
await _Private_ConnectionCloseOkAsync(cancellationToken)
852+
.ConfigureAwait(false);
854853
SetCloseReason(Session.Connection.CloseReason);
855854
}
856855
catch (IOException)
@@ -863,6 +862,8 @@ protected void HandleConnectionClose(in IncomingCommand cmd)
863862
// Ignored. We're only trying to be polite by sending
864863
// the close-ok, after all.
865864
}
865+
866+
return true;
866867
}
867868
finally
868869
{
@@ -955,11 +956,9 @@ protected bool HandleQueueDeclareOk(in IncomingCommand cmd)
955956

956957
public abstract Task _Private_ChannelCloseOkAsync(CancellationToken cancellationToken);
957958

958-
// TODO async
959-
public abstract void _Private_ChannelFlowOk(bool active);
959+
public abstract Task _Private_ChannelFlowOkAsync(bool active, CancellationToken cancellationToken);
960960

961-
// TODO async
962-
public abstract void _Private_ConnectionCloseOk();
961+
public abstract Task _Private_ConnectionCloseOkAsync(CancellationToken cancellationToken);
963962

964963
public abstract ValueTask BasicAckAsync(ulong deliveryTag, bool multiple);
965964

0 commit comments

Comments
 (0)