@@ -64,15 +64,17 @@ internal sealed class AutorecoveringConnection : IConnection
64
64
65
65
private readonly object _recordedEntitiesLock = new object ( ) ;
66
66
67
- private readonly List < AutorecoveringModel > _models = new List < AutorecoveringModel > ( ) ;
67
+ private readonly IDictionary < string , RecordedExchange > _recordedExchanges = new Dictionary < string , RecordedExchange > ( ) ;
68
68
69
- private readonly ConcurrentDictionary < RecordedBinding , byte > _recordedBindings =
70
- new ConcurrentDictionary < RecordedBinding , byte > ( ) ;
69
+ private readonly IDictionary < string , RecordedQueue > _recordedQueues = new Dictionary < string , RecordedQueue > ( ) ;
71
70
72
- private EventHandler < ConnectionBlockedEventArgs > _recordedBlockedEventHandlers ;
71
+ private readonly IDictionary < RecordedBinding , byte > _recordedBindings = new Dictionary < RecordedBinding , byte > ( ) ;
72
+
73
+ private readonly IDictionary < string , RecordedConsumer > _recordedConsumers = new Dictionary < string , RecordedConsumer > ( ) ;
73
74
74
- private readonly IDictionary < string , RecordedConsumer > _recordedConsumers =
75
- new ConcurrentDictionary < string , RecordedConsumer > ( ) ;
75
+ private readonly ICollection < AutorecoveringModel > _models = new List < AutorecoveringModel > ( ) ;
76
+
77
+ private EventHandler < ConnectionBlockedEventArgs > _recordedBlockedEventHandlers ;
76
78
private EventHandler < ShutdownEventArgs > _recordedShutdownEventHandlers ;
77
79
private EventHandler < EventArgs > _recordedUnblockedEventHandlers ;
78
80
@@ -301,7 +303,7 @@ public void DeleteRecordedBinding(RecordedBinding rb)
301
303
{
302
304
lock ( _recordedEntitiesLock )
303
305
{
304
- ( ( IDictionary < RecordedBinding , byte > ) _recordedBindings ) . Remove ( rb ) ;
306
+ _recordedBindings . Remove ( rb ) ;
305
307
}
306
308
}
307
309
@@ -324,11 +326,11 @@ public void DeleteRecordedExchange(string name)
324
326
{
325
327
lock ( _recordedEntitiesLock )
326
328
{
327
- RecordedExchanges . Remove ( name ) ;
329
+ _recordedExchanges . Remove ( name ) ;
328
330
329
331
// find bindings that need removal, check if some auto-delete exchanges
330
332
// might need the same
331
- IEnumerable < RecordedBinding > bs = _recordedBindings . Keys . Where ( b => name . Equals ( b . Destination ) ) ;
333
+ IEnumerable < RecordedBinding > bs = _recordedBindings . Keys . Where ( b => name . Equals ( b . Destination ) ) . ToArray ( ) ;
332
334
foreach ( RecordedBinding b in bs )
333
335
{
334
336
DeleteRecordedBinding ( b ) ;
@@ -341,10 +343,10 @@ public void DeleteRecordedQueue(string name)
341
343
{
342
344
lock ( _recordedEntitiesLock )
343
345
{
344
- RecordedQueues . Remove ( name ) ;
346
+ _recordedQueues . Remove ( name ) ;
345
347
// find bindings that need removal, check if some auto-delete exchanges
346
348
// might need the same
347
- IEnumerable < RecordedBinding > bs = _recordedBindings . Keys . Where ( b => name . Equals ( b . Destination ) ) ;
349
+ IEnumerable < RecordedBinding > bs = _recordedBindings . Keys . Where ( b => name . Equals ( b . Destination ) ) . ToArray ( ) ;
348
350
foreach ( RecordedBinding b in bs )
349
351
{
350
352
DeleteRecordedBinding ( b ) ;
@@ -371,13 +373,13 @@ public void MaybeDeleteRecordedAutoDeleteExchange(string exchange)
371
373
{
372
374
if ( ! HasMoreDestinationsBoundToExchange ( _recordedBindings . Keys , exchange ) )
373
375
{
374
- RecordedExchanges . TryGetValue ( exchange , out RecordedExchange rx ) ;
376
+ _recordedExchanges . TryGetValue ( exchange , out RecordedExchange rx ) ;
375
377
// last binding where this exchange is the source is gone,
376
378
// remove recorded exchange
377
379
// if it is auto-deleted. See bug 26364.
378
380
if ( ( rx != null ) && rx . IsAutoDelete )
379
381
{
380
- RecordedExchanges . Remove ( exchange ) ;
382
+ _recordedExchanges . Remove ( exchange ) ;
381
383
}
382
384
}
383
385
}
@@ -389,12 +391,12 @@ public void MaybeDeleteRecordedAutoDeleteQueue(string queue)
389
391
{
390
392
if ( ! HasMoreConsumersOnQueue ( _recordedConsumers . Values , queue ) )
391
393
{
392
- RecordedQueues . TryGetValue ( queue , out RecordedQueue rq ) ;
394
+ _recordedQueues . TryGetValue ( queue , out RecordedQueue rq ) ;
393
395
// last consumer on this connection is gone, remove recorded queue
394
396
// if it is auto-deleted. See bug 26364.
395
397
if ( ( rq != null ) && rq . IsAutoDelete )
396
398
{
397
- RecordedQueues . Remove ( queue ) ;
399
+ _recordedQueues . Remove ( queue ) ;
398
400
}
399
401
}
400
402
}
@@ -404,7 +406,10 @@ public void RecordBinding(RecordedBinding rb)
404
406
{
405
407
lock ( _recordedEntitiesLock )
406
408
{
407
- _recordedBindings . TryAdd ( rb , 0 ) ;
409
+ if ( ! _recordedBindings . ContainsKey ( rb ) )
410
+ {
411
+ _recordedBindings . Add ( rb , 0 ) ;
412
+ }
408
413
}
409
414
}
410
415
@@ -423,15 +428,15 @@ public void RecordExchange(string name, RecordedExchange x)
423
428
{
424
429
lock ( _recordedEntitiesLock )
425
430
{
426
- RecordedExchanges [ name ] = x ;
431
+ _recordedExchanges [ name ] = x ;
427
432
}
428
433
}
429
434
430
435
public void RecordQueue ( string name , RecordedQueue q )
431
436
{
432
437
lock ( _recordedEntitiesLock )
433
438
{
434
- RecordedQueues [ name ] = q ;
439
+ _recordedQueues [ name ] = q ;
435
440
}
436
441
}
437
442
@@ -497,15 +502,19 @@ public void Abort()
497
502
{
498
503
StopRecoveryLoop ( ) ;
499
504
if ( _delegate . IsOpen )
505
+ {
500
506
_delegate . Abort ( ) ;
507
+ }
501
508
}
502
509
503
510
///<summary>API-side invocation of connection abort.</summary>
504
511
public void Abort ( ushort reasonCode , string reasonText )
505
512
{
506
513
StopRecoveryLoop ( ) ;
507
514
if ( _delegate . IsOpen )
515
+ {
508
516
_delegate . Abort ( reasonCode , reasonText ) ;
517
+ }
509
518
}
510
519
511
520
///<summary>API-side invocation of connection abort with timeout.</summary>
@@ -523,23 +532,29 @@ public void Abort(ushort reasonCode, string reasonText, TimeSpan timeout)
523
532
{
524
533
StopRecoveryLoop ( ) ;
525
534
if ( _delegate . IsOpen )
535
+ {
526
536
_delegate . Abort ( reasonCode , reasonText , timeout ) ;
537
+ }
527
538
}
528
539
529
540
///<summary>API-side invocation of connection.close.</summary>
530
541
public void Close ( )
531
542
{
532
543
StopRecoveryLoop ( ) ;
533
544
if ( _delegate . IsOpen )
545
+ {
534
546
_delegate . Close ( ) ;
547
+ }
535
548
}
536
549
537
550
///<summary>API-side invocation of connection.close.</summary>
538
551
public void Close ( ushort reasonCode , string reasonText )
539
552
{
540
553
StopRecoveryLoop ( ) ;
541
554
if ( _delegate . IsOpen )
555
+ {
542
556
_delegate . Close ( reasonCode , reasonText ) ;
557
+ }
543
558
}
544
559
545
560
///<summary>API-side invocation of connection.close with timeout.</summary>
@@ -565,16 +580,19 @@ public void Close(ushort reasonCode, string reasonText, TimeSpan timeout)
565
580
public IModel CreateModel ( )
566
581
{
567
582
EnsureIsOpen ( ) ;
568
- AutorecoveringModel m ;
569
- m = new AutorecoveringModel ( this ,
570
- CreateNonRecoveringModel ( ) ) ;
583
+ AutorecoveringModel m = new AutorecoveringModel ( this , CreateNonRecoveringModel ( ) ) ;
571
584
lock ( _models )
572
585
{
573
586
_models . Add ( m ) ;
574
587
}
575
588
return m ;
576
589
}
577
590
591
+ void IDisposable . Dispose ( )
592
+ {
593
+ Dispose ( true ) ;
594
+ }
595
+
578
596
public void HandleConnectionBlocked ( string reason )
579
597
{
580
598
_delegate . HandleConnectionBlocked ( reason ) ;
@@ -585,9 +603,26 @@ public void HandleConnectionUnblocked()
585
603
_delegate . HandleConnectionUnblocked ( ) ;
586
604
}
587
605
588
- void IDisposable . Dispose ( )
606
+ internal int RecordedExchangesCount
589
607
{
590
- Dispose ( true ) ;
608
+ get
609
+ {
610
+ lock ( _recordedEntitiesLock )
611
+ {
612
+ return _recordedExchanges . Count ;
613
+ }
614
+ }
615
+ }
616
+
617
+ internal int RecordedQueuesCount
618
+ {
619
+ get
620
+ {
621
+ lock ( _recordedEntitiesLock )
622
+ {
623
+ return _recordedExchanges . Count ;
624
+ }
625
+ }
591
626
}
592
627
593
628
private void Dispose ( bool disposing )
@@ -639,7 +674,7 @@ private void PropagateQueueNameChangeToBindings(string oldName, string newName)
639
674
640
675
private void PropagateQueueNameChangeToConsumers ( string oldName , string newName )
641
676
{
642
- lock ( _recordedBindings )
677
+ lock ( _recordedConsumers )
643
678
{
644
679
IEnumerable < KeyValuePair < string , RecordedConsumer > > cs = _recordedConsumers .
645
680
Where ( pair => pair . Value . Queue . Equals ( oldName ) ) ;
@@ -652,7 +687,13 @@ private void PropagateQueueNameChangeToConsumers(string oldName, string newName)
652
687
653
688
private void RecoverBindings ( )
654
689
{
655
- foreach ( RecordedBinding b in _recordedBindings . Keys )
690
+ IDictionary < RecordedBinding , byte > recordedBindingsCopy = null ;
691
+ lock ( _recordedBindings )
692
+ {
693
+ recordedBindingsCopy = _recordedBindings . ToDictionary ( e => e . Key , e => e . Value ) ;
694
+ }
695
+
696
+ foreach ( RecordedBinding b in recordedBindingsCopy . Keys )
656
697
{
657
698
try
658
699
{
@@ -717,7 +758,13 @@ private void RecoverConnectionUnblockedHandlers()
717
758
718
759
private void RecoverConsumers ( )
719
760
{
720
- foreach ( KeyValuePair < string , RecordedConsumer > pair in _recordedConsumers )
761
+ IDictionary < string , RecordedConsumer > recordedConsumersCopy = null ;
762
+ lock ( _recordedConsumers )
763
+ {
764
+ recordedConsumersCopy = _recordedConsumers . ToDictionary ( e => e . Key , e => e . Value ) ;
765
+ }
766
+
767
+ foreach ( KeyValuePair < string , RecordedConsumer > pair in recordedConsumersCopy )
721
768
{
722
769
string tag = pair . Key ;
723
770
RecordedConsumer cons = pair . Value ;
@@ -771,7 +818,13 @@ private void RecoverEntities()
771
818
772
819
private void RecoverExchanges ( )
773
820
{
774
- foreach ( RecordedExchange rx in RecordedExchanges . Values )
821
+ IDictionary < string , RecordedExchange > recordedExchangesCopy = null ;
822
+ lock ( _recordedEntitiesLock )
823
+ {
824
+ recordedExchangesCopy = _recordedExchanges . ToDictionary ( e => e . Key , e => e . Value ) ;
825
+ }
826
+
827
+ foreach ( RecordedExchange rx in recordedExchangesCopy . Values )
775
828
{
776
829
try
777
830
{
@@ -799,18 +852,24 @@ private void RecoverModels()
799
852
800
853
private void RecoverQueues ( )
801
854
{
802
- lock ( RecordedQueues )
855
+ IDictionary < string , RecordedQueue > recordedQueuesCopy = null ;
856
+ lock ( _recordedEntitiesLock )
857
+ {
858
+ recordedQueuesCopy = _recordedQueues . ToDictionary ( entry => entry . Key , entry => entry . Value ) ;
859
+ }
860
+
861
+ foreach ( KeyValuePair < string , RecordedQueue > pair in recordedQueuesCopy )
803
862
{
804
- foreach ( KeyValuePair < string , RecordedQueue > pair in RecordedQueues )
863
+ string oldName = pair . Key ;
864
+ RecordedQueue rq = pair . Value ;
865
+
866
+ try
805
867
{
806
- string oldName = pair . Key ;
807
- RecordedQueue rq = pair . Value ;
868
+ rq . Recover ( ) ;
869
+ string newName = rq . Name ;
808
870
809
- try
871
+ if ( ! oldName . Equals ( newName ) )
810
872
{
811
- rq . Recover ( ) ;
812
- string newName = rq . Name ;
813
-
814
873
// Make sure server-named queues are re-added with
815
874
// their new names.
816
875
// We only remove old name after we've updated the bindings and consumers,
@@ -840,12 +899,12 @@ private void RecoverQueues()
840
899
}
841
900
}
842
901
}
843
- catch ( Exception cause )
844
- {
845
- string s = string . Format ( "Caught an exception while recovering queue {0}: {1}" ,
846
- oldName , cause . Message ) ;
847
- HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
848
- }
902
+ }
903
+ catch ( Exception cause )
904
+ {
905
+ string s = string . Format ( "Caught an exception while recovering queue {0}: {1}" ,
906
+ oldName , cause . Message ) ;
907
+ HandleTopologyRecoveryException ( new TopologyRecoveryException ( s , cause ) ) ;
849
908
}
850
909
}
851
910
}
0 commit comments