Skip to content

Commit 234284c

Browse files
author
Simon MacMullen
committed
Merging bug22895 into default
2 parents d5230dc + 48fedd2 commit 234284c

File tree

2 files changed

+45
-34
lines changed

2 files changed

+45
-34
lines changed

projects/client/RabbitMQ.Client/src/client/impl/ConnectionBase.cs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public abstract class ConnectionBase : IConnection
8686
public static int HandshakeTimeout = 10000;
8787

8888
///<summary>Timeout used while waiting for a
89-
///connection.close-ok reply to a connection close request
89+
///connection.close-ok reply to a connection.close request
9090
///(milliseconds)</summary>
9191
public static int ConnectionCloseTimeout = 10000;
9292

@@ -368,25 +368,25 @@ void IDisposable.Dispose()
368368
}
369369
}
370370

371-
///<summary>API-side invocation of connection close.</summary>
371+
///<summary>API-side invocation of connection.close.</summary>
372372
public void Close()
373373
{
374374
Close(CommonFraming.Constants.ReplySuccess, "Goodbye", Timeout.Infinite);
375375
}
376376

377-
///<summary>API-side invocation of connection close.</summary>
377+
///<summary>API-side invocation of connection.close.</summary>
378378
public void Close(ushort reasonCode, string reasonText)
379379
{
380380
Close(reasonCode, reasonText, Timeout.Infinite);
381381
}
382382

383-
///<summary>API-side invocation of connection close with timeout.</summary>
383+
///<summary>API-side invocation of connection.close with timeout.</summary>
384384
public void Close(int timeout)
385385
{
386386
Close(CommonFraming.Constants.ReplySuccess, "Goodbye", timeout);
387387
}
388388

389-
///<summary>API-side invocation of connection close with timeout.</summary>
389+
///<summary>API-side invocation of connection.close with timeout.</summary>
390390
public void Close(ushort reasonCode, string reasonText, int timeout)
391391
{
392392
Close(new ShutdownEventArgs(ShutdownInitiator.Application, reasonCode, reasonText), false, timeout);
@@ -460,7 +460,7 @@ public void Close(ShutdownEventArgs reason, bool abort, int timeout)
460460

461461
try
462462
{
463-
// Try to send connection close
463+
// Try to send connection.close
464464
// Wait for CloseOk in the MainLoop
465465
m_session0.Transmit(ConnectionCloseWrapper(reason.ReplyCode,
466466
reason.ReplyText));
@@ -637,7 +637,8 @@ public void MainLoop()
637637
}
638638

639639
// If allowed for clean shutdown
640-
// Run limited version of the main loop
640+
// Run main loop for a limited amount of time (as defined
641+
// by ConnectionCloseTimeout).
641642
if (shutdownCleanly)
642643
{
643644
ClosingLoop();
@@ -790,8 +791,9 @@ public void NotifyReceivedCloseOk()
790791
///<summary>
791792
/// Sets the channel named in the SoftProtocolException into
792793
/// "quiescing mode", where we issue a channel.close and
793-
/// ignore everything up to the channel.close-ok reply that
794-
/// should eventually arrive.
794+
/// ignore everything except for subsequent channel.close
795+
/// messages and the channel.close-ok reply that should
796+
/// eventually arrive.
795797
///</summary>
796798
///<remarks>
797799
///<para>
@@ -816,23 +818,12 @@ public void NotifyReceivedCloseOk()
816818
///</para>
817819
///</remarks>
818820
public void QuiesceChannel(SoftProtocolException pe) {
819-
// First, construct the close request and QuiescingSession
820-
// that we'll use during the quiesce process.
821-
822-
Command request;
823-
int replyClassId;
824-
int replyMethodId;
825-
Protocol.CreateChannelClose(pe.ReplyCode,
826-
pe.Message,
827-
out request,
828-
out replyClassId,
829-
out replyMethodId);
821+
// Construct the QuiescingSession that we'll use during
822+
// the quiesce process.
830823

831824
ISession newSession = new QuiescingSession(this,
832825
pe.Channel,
833-
pe.ShutdownReason,
834-
replyClassId,
835-
replyMethodId);
826+
pe.ShutdownReason);
836827

837828
// Here we detach the session from the connection. It's
838829
// still alive: it just won't receive any further frames
@@ -851,7 +842,7 @@ public void QuiesceChannel(SoftProtocolException pe) {
851842
// our peer. The peer will respond through the lower
852843
// layers - specifically, through the QuiescingSession we
853844
// installed above.
854-
newSession.Transmit(request);
845+
newSession.Transmit(ChannelCloseWrapper(pe.ReplyCode, pe.Message));
855846
}
856847

857848
public void HandleMainLoopException(ShutdownEventArgs reason) {
@@ -959,7 +950,19 @@ public Command ConnectionCloseWrapper(ushort reasonCode, string reasonText)
959950
out replyClassId,
960951
out replyMethodId);
961952
return request;
962-
}
953+
}
954+
955+
protected Command ChannelCloseWrapper(ushort reasonCode, string reasonText)
956+
{
957+
Command request;
958+
int replyClassId, replyMethodId;
959+
Protocol.CreateChannelClose(reasonCode,
960+
reasonText,
961+
out request,
962+
out replyClassId,
963+
out replyMethodId);
964+
return request;
965+
}
963966

964967
private static uint NegotiatedMaxValue(uint clientValue, uint serverValue)
965968
{

projects/client/RabbitMQ.Client/src/client/impl/QuiescingSession.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,45 +65,53 @@
6565
// the versions we support*. Obviously we may need to revisit this if
6666
// that ever changes.
6767
using CommonFraming = RabbitMQ.Client.Framing.v0_9;
68+
using CommonFramingSpecs = RabbitMQ.Client.Framing.Impl.v0_9;
6869

6970
namespace RabbitMQ.Client.Impl
7071
{
7172
///<summary>Small ISession implementation used during channel quiescing.</summary>
7273
public class QuiescingSession: SessionBase
7374
{
7475
public ShutdownEventArgs m_reason;
75-
public int m_replyClassId;
76-
public int m_replyMethodId;
7776

7877
public QuiescingSession(ConnectionBase connection,
7978
int channelNumber,
80-
ShutdownEventArgs reason,
81-
int replyClassId,
82-
int replyMethodId)
79+
ShutdownEventArgs reason)
8380
: base(connection, channelNumber)
8481
{
8582
m_reason = reason;
86-
m_replyClassId = replyClassId;
87-
m_replyMethodId = replyMethodId;
8883
}
8984

9085
public override void HandleFrame(Frame frame)
9186
{
9287
if (frame.Type == CommonFraming.Constants.FrameMethod) {
9388
MethodBase method = Connection.Protocol.DecodeMethodFrom(frame.GetReader());
94-
if ((method.ProtocolClassId == m_replyClassId)
95-
&& (method.ProtocolMethodId == m_replyMethodId))
89+
if ((method.ProtocolClassId == CommonFramingSpecs.ChannelCloseOk.ClassId)
90+
&& (method.ProtocolMethodId == CommonFramingSpecs.ChannelCloseOk.MethodId))
9691
{
9792
// This is the reply we were looking for. Release
9893
// the channel with the reason we were passed in
9994
// our constructor.
10095
Close(m_reason);
10196
return;
10297
}
98+
else if ((method.ProtocolClassId == CommonFramingSpecs.ChannelClose.ClassId)
99+
&& (method.ProtocolMethodId == CommonFramingSpecs.ChannelClose.MethodId))
100+
{
101+
// We're already shutting down the channel, so
102+
// just send back an ok.
103+
Transmit(CreateChannelCloseOk());
104+
return;
105+
}
106+
103107
}
104108

105109
// Either a non-method frame, or not what we were looking
106110
// for. Ignore it - we're quiescing.
107111
}
112+
113+
protected Command CreateChannelCloseOk() {
114+
return new Command(new CommonFramingSpecs.ConnectionCloseOk());
115+
}
108116
}
109117
}

0 commit comments

Comments
 (0)