Skip to content

Commit 0003602

Browse files
committed
Manually port 39a9f2b to 6.x
Ports commit 39a9f2b to 6.x branch See also: #950 #938
1 parent c9201e4 commit 0003602

File tree

5 files changed

+104
-16
lines changed

5 files changed

+104
-16
lines changed

projects/RabbitMQ.Client/client/api/IAutorecoveringConnection.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,8 @@
3030
//---------------------------------------------------------------------------
3131

3232
using System;
33-
using System.Collections.Generic;
34-
using System.IO;
35-
using System.Threading;
3633

3734
using RabbitMQ.Client.Events;
38-
using RabbitMQ.Client.Exceptions;
3935

4036
namespace RabbitMQ.Client
4137
{

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,14 @@ public void Init(IEndpointResolver endpoints)
668668
Init(fh);
669669
}
670670

671+
internal IFrameHandler FrameHandler
672+
{
673+
get
674+
{
675+
return _delegate.FrameHandler;
676+
}
677+
}
678+
671679
private void Init(IFrameHandler fh)
672680
{
673681
if (_disposed)

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

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ public void Abort(ushort reasonCode, string reasonText, ShutdownInitiator initia
271271

272272
public void Close(ShutdownEventArgs reason)
273273
{
274-
Close(reason, false, Timeout.InfiniteTimeSpan);
274+
Close(reason, false, TimeSpan.FromSeconds(30));
275275
}
276276

277277
///<summary>Try to close connection in a graceful way</summary>
@@ -286,7 +286,7 @@ public void Close(ShutdownEventArgs reason)
286286
///</para>
287287
///<para>
288288
///Timeout determines how much time internal close operations should be given
289-
///to complete. System.Threading.Timeout.InfiniteTimeSpan value means infinity.
289+
///to complete.
290290
///</para>
291291
///</remarks>
292292
public void Close(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
@@ -307,7 +307,10 @@ public void Close(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
307307
{
308308
// Try to send connection.close
309309
// Wait for CloseOk in the MainLoop
310-
_session0.Transmit(ConnectionCloseWrapper(reason.ReplyCode, reason.ReplyText));
310+
if (!_closed)
311+
{
312+
_session0.Transmit(ConnectionCloseWrapper(reason.ReplyCode, reason.ReplyText));
313+
}
311314
}
312315
catch (AlreadyClosedException)
313316
{
@@ -453,9 +456,12 @@ public bool HardProtocolExceptionHandler(HardProtocolException hpe)
453456
_session0.SetSessionClosing(false);
454457
try
455458
{
456-
_session0.Transmit(ConnectionCloseWrapper(
457-
hpe.ShutdownReason.ReplyCode,
458-
hpe.ShutdownReason.ReplyText));
459+
if (!_closed)
460+
{
461+
_session0.Transmit(ConnectionCloseWrapper(
462+
hpe.ShutdownReason.ReplyCode,
463+
hpe.ShutdownReason.ReplyText));
464+
}
459465
return true;
460466
}
461467
catch (IOException ioe)
@@ -952,13 +958,13 @@ public void UpdateSecret(string newSecret, string reason)
952958
///<summary>API-side invocation of connection abort.</summary>
953959
public void Abort()
954960
{
955-
Abort(Timeout.InfiniteTimeSpan);
961+
Abort(TimeSpan.FromSeconds(5));
956962
}
957963

958964
///<summary>API-side invocation of connection abort.</summary>
959965
public void Abort(ushort reasonCode, string reasonText)
960966
{
961-
Abort(reasonCode, reasonText, Timeout.InfiniteTimeSpan);
967+
Abort(reasonCode, reasonText, TimeSpan.FromSeconds(5));
962968
}
963969

964970
///<summary>API-side invocation of connection abort with timeout.</summary>
@@ -976,13 +982,13 @@ public void Abort(ushort reasonCode, string reasonText, TimeSpan timeout)
976982
///<summary>API-side invocation of connection.close.</summary>
977983
public void Close()
978984
{
979-
Close(Constants.ReplySuccess, "Goodbye", Timeout.InfiniteTimeSpan);
985+
Close(Constants.ReplySuccess, "Goodbye", TimeSpan.FromSeconds(30));
980986
}
981987

982988
///<summary>API-side invocation of connection.close.</summary>
983989
public void Close(ushort reasonCode, string reasonText)
984990
{
985-
Close(reasonCode, reasonText, Timeout.InfiniteTimeSpan);
991+
Close(reasonCode, reasonText, TimeSpan.FromSeconds(30));
986992
}
987993

988994
///<summary>API-side invocation of connection.close with timeout.</summary>
@@ -1058,7 +1064,16 @@ internal OutgoingCommand ChannelCloseWrapper(ushort reasonCode, string reasonTex
10581064
return request;
10591065
}
10601066

1061-
void StartAndTune()
1067+
///<summary>Used for testing only.</summary>
1068+
internal IFrameHandler FrameHandler
1069+
{
1070+
get
1071+
{
1072+
return _frameHandler;
1073+
}
1074+
}
1075+
1076+
private void StartAndTune()
10621077
{
10631078
var connectionStartCell = new BlockingCell<ConnectionStartDetails>();
10641079
_model0.m_connectionStartCell = connectionStartCell;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ public void Close()
188188
{
189189
lock (_semaphore)
190190
{
191-
if (!_closed)
191+
if (_closed || _socket == null)
192+
{
193+
return;
194+
}
195+
else
192196
{
193197
try
194198
{

projects/Unit/TestConnectionShutdown.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,77 @@
3535
using NUnit.Framework;
3636

3737
using RabbitMQ.Client.Impl;
38+
using RabbitMQ.Client.Framing.Impl;
3839

3940
namespace RabbitMQ.Client.Unit
4041
{
4142
[TestFixture]
4243
public class TestConnectionShutdown : IntegrationFixture
4344
{
45+
[Test]
46+
public void TestCleanClosureWithSocketClosedOutOfBand()
47+
{
48+
using (IConnection conn = CreateAutorecoveringConnection())
49+
{
50+
using (IModel model = conn.CreateModel())
51+
{
52+
var latch = new ManualResetEventSlim(false);
53+
model.ModelShutdown += (m, args) => {
54+
latch.Set();
55+
};
56+
57+
var c = (AutorecoveringConnection)conn;
58+
c.FrameHandler.Close();
59+
60+
conn.Close(TimeSpan.FromSeconds(4));
61+
Wait(latch, TimeSpan.FromSeconds(5));
62+
}
63+
}
64+
}
65+
66+
[Test]
67+
public void TestAbortWithSocketClosedOutOfBand()
68+
{
69+
using (IConnection conn = CreateAutorecoveringConnection())
70+
{
71+
using (IModel model = conn.CreateModel())
72+
{
73+
var latch = new ManualResetEventSlim(false);
74+
model.ModelShutdown += (m, args) => {
75+
latch.Set();
76+
};
77+
78+
var c = (AutorecoveringConnection)conn;
79+
c.FrameHandler.Close();
80+
81+
conn.Abort();
82+
// default Connection.Abort() timeout and then some
83+
Wait(latch, TimeSpan.FromSeconds(6));
84+
}
85+
}
86+
}
87+
88+
[Test]
89+
public void TestDisposedWithSocketClosedOutOfBand()
90+
{
91+
using (IConnection conn = CreateAutorecoveringConnection())
92+
{
93+
using (IModel model = conn.CreateModel())
94+
{
95+
var latch = new ManualResetEventSlim(false);
96+
model.ModelShutdown += (m, args) => {
97+
latch.Set();
98+
};
99+
100+
var c = (AutorecoveringConnection)conn;
101+
c.FrameHandler.Close();
102+
103+
conn.Dispose();
104+
Wait(latch, TimeSpan.FromSeconds(3));
105+
}
106+
}
107+
}
108+
44109
[Test]
45110
public void TestShutdownSignalPropagationToChannels()
46111
{

0 commit comments

Comments
 (0)