Skip to content

Commit fd695ef

Browse files
committed
add events for connection recovery errors and connection success.
1 parent 80425dc commit fd695ef

File tree

5 files changed

+171
-4
lines changed

5 files changed

+171
-4
lines changed

projects/client/RabbitMQ.Client/src/client/api/IConnection.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ public interface IConnection : NetworkConnection, IDisposable
170170
/// of those event handlers throws an exception, as well.
171171
/// </remarks>
172172
event EventHandler<CallbackExceptionEventArgs> CallbackException;
173+
event EventHandler<EventArgs> RecoverySucceeded;
174+
event EventHandler<ConnectionRecoveryErrorEventArgs> ConnectionRecoveryError;
175+
173176

174177
event EventHandler<ConnectionBlockedEventArgs> ConnectionBlocked;
175178

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// This source code is dual-licensed under the Apache License, version
2+
// 2.0, and the Mozilla Public License, version 1.1.
3+
//
4+
// The APL v2.0:
5+
//
6+
//---------------------------------------------------------------------------
7+
// Copyright (c) 2007-2016 Pivotal Software, 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+
// http://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 v1.1:
23+
//
24+
//---------------------------------------------------------------------------
25+
// The contents of this file are subject to the Mozilla Public License
26+
// Version 1.1 (the "License"); you may not use this file except in
27+
// compliance with the License. You may obtain a copy of the License
28+
// at http://www.mozilla.org/MPL/
29+
//
30+
// Software distributed under the License is distributed on an "AS IS"
31+
// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
32+
// the License for the specific language governing rights and
33+
// limitations under the License.
34+
//
35+
// The Original Code is RabbitMQ.
36+
//
37+
// The Initial Developer of the Original Code is Pivotal Software, Inc.
38+
// Copyright (c) 2007-2016 Pivotal Software, Inc. All rights reserved.
39+
//---------------------------------------------------------------------------
40+
41+
using System;
42+
43+
namespace RabbitMQ.Client.Events
44+
{
45+
public sealed class ConnectionRecoveryErrorEventArgs : EventArgs
46+
{
47+
public ConnectionRecoveryErrorEventArgs(Exception ex)
48+
{
49+
Exception = ex;
50+
}
51+
52+
public Exception Exception { get; private set; }
53+
}
54+
}

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

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public class AutorecoveringConnection : IConnection, IRecoverable
9898
private EventHandler<QueueNameChangedAfterRecoveryEventArgs> m_queueNameChange;
9999
private EventHandler<EventArgs> m_recovery;
100100

101+
private EventHandler<ConnectionRecoveryErrorEventArgs> m_connectionRecoveryError;
102+
101103
public AutorecoveringConnection(ConnectionFactory factory, string clientProvidedName = null)
102104
{
103105
m_factory = factory;
@@ -121,6 +123,42 @@ private bool ManuallyClosed
121123
}
122124
}
123125

126+
public event EventHandler<EventArgs> RecoverySucceeded
127+
{
128+
add
129+
{
130+
lock (m_eventLock)
131+
{
132+
m_recovery += value;
133+
}
134+
}
135+
remove
136+
{
137+
lock (m_eventLock)
138+
{
139+
m_recovery -= value;
140+
}
141+
}
142+
}
143+
144+
public event EventHandler<ConnectionRecoveryErrorEventArgs> ConnectionRecoveryError
145+
{
146+
add
147+
{
148+
lock (m_eventLock)
149+
{
150+
m_connectionRecoveryError += value;
151+
}
152+
}
153+
remove
154+
{
155+
lock (m_eventLock)
156+
{
157+
m_connectionRecoveryError -= value;
158+
}
159+
}
160+
}
161+
124162
public event EventHandler<CallbackExceptionEventArgs> CallbackException
125163
{
126164
add
@@ -235,6 +273,7 @@ public event EventHandler<QueueNameChangedAfterRecoveryEventArgs> QueueNameChang
235273
}
236274
}
237275

276+
[Obsolete("Use RecoverySucceeded instead")]
238277
public event EventHandler<EventArgs> Recovery
239278
{
240279
add
@@ -798,14 +837,33 @@ protected void RecoverConnectionDelegate()
798837
m_delegate = new Connection(m_factory, false, fh, this.ClientProvidedName);
799838
recovering = false;
800839
}
801-
catch (Exception)
840+
catch (Exception e)
802841
{
842+
// Trigger recovery error event
843+
var handler = m_connectionRecoveryError;
844+
if (handler != null)
845+
{
846+
var args = new ConnectionRecoveryErrorEventArgs(e);
847+
foreach (EventHandler<ConnectionRecoveryErrorEventArgs> h in handler.GetInvocationList())
848+
{
849+
try
850+
{
851+
h(this, args);
852+
}
853+
catch (Exception ex)
854+
{
855+
var a = new CallbackExceptionEventArgs(ex);
856+
a.Detail["context"] = "OnConnectionRecoveryError";
857+
m_delegate.OnCallbackException(a);
858+
}
859+
}
860+
}
803861
#if NETFX_CORE
804862
System.Threading.Tasks.Task.Delay(m_factory.NetworkRecoveryInterval).Wait();
805863
#else
806864
Thread.Sleep(m_factory.NetworkRecoveryInterval);
807865
#endif
808-
// TODO: provide a way to handle these exceptions
866+
// TODO: provide a way to handle these exceptions
809867
}
810868
}
811869
}

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
using System.Net.Sockets;
5858
#endif
5959

60-
using System.Reflection;
6160
using System.Text;
6261
using System.Threading;
6362

@@ -72,6 +71,8 @@ public class Connection : IConnection
7271

7372
private ManualResetEvent m_appContinuation = new ManualResetEvent(false);
7473
private EventHandler<CallbackExceptionEventArgs> m_callbackException;
74+
private EventHandler<EventArgs> m_recoverySucceeded;
75+
private EventHandler<ConnectionRecoveryErrorEventArgs> connectionRecoveryFailure;
7576

7677
private IDictionary<string, object> m_clientProperties;
7778

@@ -81,6 +82,7 @@ public class Connection : IConnection
8182
private EventHandler<ConnectionBlockedEventArgs> m_connectionBlocked;
8283
private EventHandler<ShutdownEventArgs> m_connectionShutdown;
8384
private EventHandler<EventArgs> m_connectionUnblocked;
85+
8486
private IConnectionFactory m_factory;
8587
private IFrameHandler m_frameHandler;
8688

@@ -130,6 +132,24 @@ public Connection(IConnectionFactory factory, bool insist, IFrameHandler frameHa
130132

131133
public Guid Id { get { return m_id; } }
132134

135+
public event EventHandler<EventArgs> RecoverySucceeded
136+
{
137+
add
138+
{
139+
lock (m_eventLock)
140+
{
141+
m_recoverySucceeded += value;
142+
}
143+
}
144+
remove
145+
{
146+
lock (m_eventLock)
147+
{
148+
m_recoverySucceeded -= value;
149+
}
150+
}
151+
}
152+
133153
public event EventHandler<CallbackExceptionEventArgs> CallbackException
134154
{
135155
add
@@ -211,6 +231,23 @@ public event EventHandler<EventArgs> ConnectionUnblocked
211231
}
212232
}
213233

234+
public event EventHandler<ConnectionRecoveryErrorEventArgs> ConnectionRecoveryError
235+
{
236+
add
237+
{
238+
lock (m_eventLock)
239+
{
240+
connectionRecoveryFailure += value;
241+
}
242+
}
243+
remove
244+
{
245+
lock (m_eventLock)
246+
{
247+
connectionRecoveryFailure -= value;
248+
}
249+
}
250+
}
214251
public string ClientProvidedName { get; private set; }
215252

216253
public bool AutoClose

projects/client/Unit/src/unit/TestConnectionRecovery.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public void TestBasicConnectionRecoveryWithEndpointList()
163163
{
164164
using(var c = CreateAutorecoveringConnection(
165165
new List<AmqpTcpEndpoint>
166-
{
166+
{
167167
new AmqpTcpEndpoint("127.0.0.1"),
168168
new AmqpTcpEndpoint("localhost")
169169
}))
@@ -174,6 +174,21 @@ public void TestBasicConnectionRecoveryWithEndpointList()
174174
}
175175
}
176176

177+
[Test]
178+
public void TestBasicConnectionRecoveryErrorEvent()
179+
{
180+
Assert.IsTrue(Conn.IsOpen);
181+
using(var c = CreateAutorecoveringConnection())
182+
{
183+
var latch = new AutoResetEvent(false);
184+
c.ConnectionRecoveryError += (o, _args) => latch.Set();
185+
StopRabbitMQ();
186+
latch.WaitOne(30000);
187+
StartRabbitMQ();
188+
WaitForRecovery(c);
189+
}
190+
}
191+
177192
[Test]
178193
public void TestBasicConnectionRecoveryWithEndpointListAndUnreachableHosts()
179194
{

0 commit comments

Comments
 (0)