@@ -428,11 +428,11 @@ private bool TryPerformAutomaticRecovery()
428
428
// 2. Recover queues
429
429
// 3. Recover bindings
430
430
// 4. Recover consumers
431
- using ( var recoveryModel = _delegate . CreateModel ( ) )
431
+ using ( var recoveryModelFactory = new RecoveryModelFactory ( _delegate ) )
432
432
{
433
- RecoverExchanges ( recoveryModel ) ;
434
- RecoverQueues ( recoveryModel ) ;
435
- RecoverBindings ( recoveryModel ) ;
433
+ RecoverExchanges ( recoveryModelFactory ) ;
434
+ RecoverQueues ( recoveryModelFactory ) ;
435
+ RecoverBindings ( recoveryModelFactory ) ;
436
436
}
437
437
}
438
438
@@ -985,7 +985,7 @@ private void PropagateQueueNameChangeToConsumers(string oldName, string newName)
985
985
}
986
986
}
987
987
988
- private void RecoverBindings ( IModel model )
988
+ private void RecoverBindings ( RecoveryModelFactory recoveryModelFactory )
989
989
{
990
990
Dictionary < RecordedBinding , byte > recordedBindingsCopy ;
991
991
lock ( _recordedEntitiesLock )
@@ -997,13 +997,21 @@ private void RecoverBindings(IModel model)
997
997
{
998
998
try
999
999
{
1000
- b . Recover ( model ) ;
1000
+ b . Recover ( recoveryModelFactory . RecoveryModel ) ;
1001
1001
}
1002
1002
catch ( Exception cause )
1003
1003
{
1004
- string s = string . Format ( "Caught an exception while recovering binding between {0} and {1}: {2}" ,
1005
- b . Source , b . Destination , cause . Message ) ;
1006
- HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1004
+ if ( _factory . TopologyRecoveryExceptionHandler . BindingRecoveryExceptionHandler != null
1005
+ && _factory . TopologyRecoveryExceptionHandler . BindingRecoveryExceptionCondition ( b , cause ) )
1006
+ {
1007
+ _factory . TopologyRecoveryExceptionHandler . BindingRecoveryExceptionHandler ( b , cause ) ;
1008
+ }
1009
+ else
1010
+ {
1011
+ string s = string . Format ( "Caught an exception while recovering binding between {0} and {1}: {2}" ,
1012
+ b . Source , b . Destination , cause . Message ) ;
1013
+ HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1014
+ }
1007
1015
}
1008
1016
}
1009
1017
}
@@ -1139,14 +1147,23 @@ internal void RecoverConsumers(AutorecoveringModel modelToRecover, IModel channe
1139
1147
}
1140
1148
catch ( Exception cause )
1141
1149
{
1142
- string s = string . Format ( "Caught an exception while recovering consumer {0} on queue {1}: {2}" ,
1143
- tag , cons . Queue , cause . Message ) ;
1144
- HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1150
+ if ( channelToUse . IsOpen
1151
+ && _factory . TopologyRecoveryExceptionHandler . ConsumerRecoveryExceptionHandler != null
1152
+ && _factory . TopologyRecoveryExceptionHandler . ConsumerRecoveryExceptionCondition ( cons , cause ) )
1153
+ {
1154
+ _factory . TopologyRecoveryExceptionHandler . ConsumerRecoveryExceptionHandler ( cons , cause ) ;
1155
+ }
1156
+ else
1157
+ {
1158
+ string s = string . Format ( "Caught an exception while recovering consumer {0} on queue {1}: {2}" ,
1159
+ tag , cons . Queue , cause . Message ) ;
1160
+ HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1161
+ }
1145
1162
}
1146
1163
}
1147
1164
}
1148
1165
1149
- private void RecoverExchanges ( IModel model )
1166
+ private void RecoverExchanges ( RecoveryModelFactory recoveryModelFactory )
1150
1167
{
1151
1168
Dictionary < string , RecordedExchange > recordedExchangesCopy ;
1152
1169
lock ( _recordedEntitiesLock )
@@ -1158,13 +1175,21 @@ private void RecoverExchanges(IModel model)
1158
1175
{
1159
1176
try
1160
1177
{
1161
- rx . Recover ( model ) ;
1178
+ rx . Recover ( recoveryModelFactory . RecoveryModel ) ;
1162
1179
}
1163
1180
catch ( Exception cause )
1164
1181
{
1165
- string s = string . Format ( "Caught an exception while recovering exchange {0}: {1}" ,
1166
- rx . Name , cause . Message ) ;
1167
- HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1182
+ if ( _factory . TopologyRecoveryExceptionHandler . ExchangeRecoveryExceptionHandler != null
1183
+ && _factory . TopologyRecoveryExceptionHandler . ExchangeRecoveryExceptionCondition ( rx , cause ) )
1184
+ {
1185
+ _factory . TopologyRecoveryExceptionHandler . ExchangeRecoveryExceptionHandler ( rx , cause ) ;
1186
+ }
1187
+ else
1188
+ {
1189
+ string s = string . Format ( "Caught an exception while recovering exchange {0}: {1}" ,
1190
+ rx . Name , cause . Message ) ;
1191
+ HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1192
+ }
1168
1193
}
1169
1194
}
1170
1195
}
@@ -1180,7 +1205,7 @@ private void RecoverModelsAndItsConsumers()
1180
1205
}
1181
1206
}
1182
1207
1183
- private void RecoverQueues ( IModel model )
1208
+ private void RecoverQueues ( RecoveryModelFactory recoveryModelFactory )
1184
1209
{
1185
1210
Dictionary < string , RecordedQueue > recordedQueuesCopy ;
1186
1211
lock ( _recordedEntitiesLock )
@@ -1195,7 +1220,7 @@ private void RecoverQueues(IModel model)
1195
1220
1196
1221
try
1197
1222
{
1198
- rq . Recover ( model ) ;
1223
+ rq . Recover ( recoveryModelFactory . RecoveryModel ) ;
1199
1224
string newName = rq . Name ;
1200
1225
1201
1226
if ( ! oldName . Equals ( newName ) )
@@ -1232,9 +1257,17 @@ private void RecoverQueues(IModel model)
1232
1257
}
1233
1258
catch ( Exception cause )
1234
1259
{
1235
- string s = string . Format ( "Caught an exception while recovering queue {0}: {1}" ,
1236
- oldName , cause . Message ) ;
1237
- HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1260
+ if ( _factory . TopologyRecoveryExceptionHandler . QueueRecoveryExceptionHandler != null
1261
+ && _factory . TopologyRecoveryExceptionHandler . QueueRecoveryExceptionCondition ( rq , cause ) )
1262
+ {
1263
+ _factory . TopologyRecoveryExceptionHandler . QueueRecoveryExceptionHandler ( rq , cause ) ;
1264
+ }
1265
+ else
1266
+ {
1267
+ string s = string . Format ( "Caught an exception while recovering queue {0}: {1}" ,
1268
+ oldName , cause . Message ) ;
1269
+ HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
1270
+ }
1238
1271
}
1239
1272
}
1240
1273
}
@@ -1295,6 +1328,45 @@ private enum RecoveryConnectionState
1295
1328
Recovering
1296
1329
}
1297
1330
1331
+ private sealed class RecoveryModelFactory : IDisposable
1332
+ {
1333
+ private readonly IConnection _connection ;
1334
+ private IModel _recoveryModel ;
1335
+
1336
+ public RecoveryModelFactory ( IConnection connection )
1337
+ {
1338
+ _connection = connection ;
1339
+ }
1340
+
1341
+ public IModel RecoveryModel
1342
+ {
1343
+ get
1344
+ {
1345
+ if ( _recoveryModel == null )
1346
+ {
1347
+ _recoveryModel = _connection . CreateModel ( ) ;
1348
+ }
1349
+
1350
+ if ( _recoveryModel . IsClosed )
1351
+ {
1352
+ _recoveryModel . Dispose ( ) ;
1353
+ _recoveryModel = _connection . CreateModel ( ) ;
1354
+ }
1355
+
1356
+ return _recoveryModel ;
1357
+ }
1358
+ }
1359
+
1360
+ public void Dispose ( )
1361
+ {
1362
+ if ( _recoveryModel != null )
1363
+ {
1364
+ _recoveryModel . Close ( ) ;
1365
+ _recoveryModel . Dispose ( ) ;
1366
+ }
1367
+ }
1368
+ }
1369
+
1298
1370
private Task _recoveryTask ;
1299
1371
private RecoveryConnectionState _recoveryLoopState = RecoveryConnectionState . Connected ;
1300
1372
0 commit comments