44
55using System . Collections ;
66using System . Collections . Concurrent ;
7+ using System . Collections . ObjectModel ;
78using System . Text ;
89using System . Text . Json ;
910using Steeltoe . Common ;
@@ -17,11 +18,8 @@ namespace Steeltoe.Discovery.Eureka.AppInfo;
1718/// </summary>
1819public sealed class ApplicationInfoCollection : IReadOnlyCollection < ApplicationInfo >
1920{
20- private readonly object _addRemoveInstanceLock = new ( ) ;
21-
2221 internal ConcurrentDictionary < string , ApplicationInfo > ApplicationMap { get ; } = new ( ) ;
2322 internal ConcurrentDictionary < string , ConcurrentDictionary < string , InstanceInfo > > VipInstanceMap { get ; } = new ( ) ;
24- internal ConcurrentDictionary < string , ConcurrentDictionary < string , InstanceInfo > > SecureVipInstanceMap { get ; } = new ( ) ;
2523
2624 public string ? AppsHashCode { get ; internal set ; }
2725 public long ? Version { get ; private set ; }
@@ -51,18 +49,25 @@ internal ApplicationInfoCollection(IList<ApplicationInfo> apps)
5149 return ApplicationMap . GetValueOrDefault ( appName . ToUpperInvariant ( ) ) ;
5250 }
5351
54- internal List < InstanceInfo > GetInstancesBySecureVipAddress ( string secureVipAddress )
52+ internal ReadOnlyCollection < InstanceInfo > GetInstancesByVipAddress ( string vipAddress )
5553 {
56- ArgumentException . ThrowIfNullOrWhiteSpace ( secureVipAddress ) ;
54+ ArgumentException . ThrowIfNullOrWhiteSpace ( vipAddress ) ;
5755
58- return GetByVipAddress ( secureVipAddress , SecureVipInstanceMap ) ;
59- }
56+ List < InstanceInfo > result = [ ] ;
57+ string addressUpper = vipAddress . ToUpperInvariant ( ) ;
6058
61- internal List < InstanceInfo > GetInstancesByVipAddress ( string vipAddress )
62- {
63- ArgumentException . ThrowIfNullOrWhiteSpace ( vipAddress ) ;
59+ if ( VipInstanceMap . TryGetValue ( addressUpper , out ConcurrentDictionary < string , InstanceInfo > ? instancesById ) )
60+ {
61+ foreach ( InstanceInfo instance in instancesById . Values )
62+ {
63+ if ( ( ReturnUpInstancesOnly && instance . EffectiveStatus == InstanceStatus . Up ) || ! ReturnUpInstancesOnly )
64+ {
65+ result . Add ( instance ) ;
66+ }
67+ }
68+ }
6469
65- return GetByVipAddress ( vipAddress , VipInstanceMap ) ;
70+ return result . AsReadOnly ( ) ;
6671 }
6772
6873 /// <inheritdoc />
@@ -92,79 +97,51 @@ internal void Add(ApplicationInfo app)
9297
9398 foreach ( InstanceInfo instance in app . Instances )
9499 {
95- AddInstanceToVip ( instance ) ;
100+ AddToVipInstanceMap ( instance ) ;
96101 }
97102 }
98103
99- private void AddInstanceToVip ( InstanceInfo instance )
104+ private void AddToVipInstanceMap ( InstanceInfo instance )
100105 {
101- foreach ( string vipAddress in ExpandVipAddresses ( instance . VipAddress ) )
106+ foreach ( string vipAddress in ExpandVipAddresses ( instance ) )
102107 {
103- AddInstanceToVip ( instance , vipAddress , VipInstanceMap ) ;
104- }
108+ string addressUpper = vipAddress . ToUpperInvariant ( ) ;
105109
106- foreach ( string secureVipAddress in ExpandVipAddresses ( instance . SecureVipAddress ) )
107- {
108- AddInstanceToVip ( instance , secureVipAddress , SecureVipInstanceMap ) ;
110+ ConcurrentDictionary < string , InstanceInfo > instancesById = VipInstanceMap . GetOrAdd ( addressUpper , new ConcurrentDictionary < string , InstanceInfo > ( ) ) ;
111+ instancesById . AddOrUpdate ( instance . InstanceId , _ => instance , ( _ , _ ) => instance ) ;
109112 }
110113 }
111114
112- private void AddInstanceToVip ( InstanceInfo instance , string address , ConcurrentDictionary < string , ConcurrentDictionary < string , InstanceInfo > > dictionary )
115+ private static HashSet < string > ExpandVipAddresses ( InstanceInfo instance )
113116 {
114- lock ( _addRemoveInstanceLock )
115- {
116- string addressUpper = address . ToUpperInvariant ( ) ;
117-
118- if ( ! dictionary . TryGetValue ( addressUpper , out ConcurrentDictionary < string , InstanceInfo > ? instances ) )
119- {
120- instances = new ConcurrentDictionary < string , InstanceInfo > ( ) ;
121- dictionary [ addressUpper ] = instances ;
122- }
117+ HashSet < string > addresses = [ ] ;
123118
124- instances [ instance . InstanceId ] = instance ;
119+ if ( instance . SecureVipAddress != null )
120+ {
121+ string [ ] secureAddresses = instance . SecureVipAddress . Split ( ',' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
122+ addresses . UnionWith ( secureAddresses ) ;
125123 }
126- }
127124
128- private static string [ ] ExpandVipAddresses ( string ? addresses )
129- {
130- if ( string . IsNullOrWhiteSpace ( addresses ) )
125+ if ( instance . VipAddress != null )
131126 {
132- return [ ] ;
127+ string [ ] vipAddresses = instance . VipAddress . Split ( ',' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
128+ addresses . UnionWith ( vipAddresses ) ;
133129 }
134130
135- return addresses . Split ( ',' , StringSplitOptions . TrimEntries | StringSplitOptions . RemoveEmptyEntries ) ;
131+ return addresses ;
136132 }
137133
138- internal void RemoveInstanceFromVip ( InstanceInfo instance )
134+ internal void RemoveFromVipInstanceMap ( InstanceInfo instance )
139135 {
140136 ArgumentNullException . ThrowIfNull ( instance ) ;
141137
142- foreach ( string vipAddress in ExpandVipAddresses ( instance . VipAddress ) )
143- {
144- RemoveInstanceFromVip ( instance , vipAddress , VipInstanceMap ) ;
145- }
146-
147- foreach ( string secureVipAddress in ExpandVipAddresses ( instance . SecureVipAddress ) )
148- {
149- RemoveInstanceFromVip ( instance , secureVipAddress , SecureVipInstanceMap ) ;
150- }
151- }
152-
153- private void RemoveInstanceFromVip ( InstanceInfo instance , string address ,
154- ConcurrentDictionary < string , ConcurrentDictionary < string , InstanceInfo > > dictionary )
155- {
156- lock ( _addRemoveInstanceLock )
138+ foreach ( string vipAddress in ExpandVipAddresses ( instance ) )
157139 {
158- string addressUpper = address . ToUpperInvariant ( ) ;
140+ string addressUpper = vipAddress . ToUpperInvariant ( ) ;
159141
160- if ( dictionary . TryGetValue ( addressUpper , out ConcurrentDictionary < string , InstanceInfo > ? instances ) )
142+ if ( VipInstanceMap . TryGetValue ( addressUpper , out ConcurrentDictionary < string , InstanceInfo > ? instancesById ) )
161143 {
162- _ = instances . TryRemove ( instance . InstanceId , out _ ) ;
163-
164- if ( instances . IsEmpty )
165- {
166- _ = dictionary . TryRemove ( addressUpper , out _ ) ;
167- }
144+ instancesById . TryRemove ( instance . InstanceId , out _ ) ;
168145 }
169146 }
170147 }
@@ -190,11 +167,11 @@ internal void UpdateFromDelta(ApplicationInfoCollection delta)
190167 case ActionType . Added :
191168 case ActionType . Modified :
192169 existingApp . Add ( instance ) ;
193- AddInstanceToVip ( instance ) ;
170+ AddToVipInstanceMap ( instance ) ;
194171 break ;
195172 case ActionType . Deleted :
196173 existingApp . Remove ( instance ) ;
197- RemoveInstanceFromVip ( instance ) ;
174+ RemoveFromVipInstanceMap ( instance ) ;
198175 break ;
199176 }
200177 }
@@ -261,22 +238,4 @@ internal static ApplicationInfoCollection FromJson(JsonApplications? jsonApplica
261238
262239 return apps ;
263240 }
264-
265- private List < InstanceInfo > GetByVipAddress ( string name , ConcurrentDictionary < string , ConcurrentDictionary < string , InstanceInfo > > dictionary )
266- {
267- List < InstanceInfo > result = [ ] ;
268-
269- if ( dictionary . TryGetValue ( name . ToUpperInvariant ( ) , out ConcurrentDictionary < string , InstanceInfo > ? instances ) )
270- {
271- foreach ( InstanceInfo instance in instances . Values . ToArray ( ) )
272- {
273- if ( ( ReturnUpInstancesOnly && instance . EffectiveStatus == InstanceStatus . Up ) || ! ReturnUpInstancesOnly )
274- {
275- result . Add ( instance ) ;
276- }
277- }
278- }
279-
280- return result ;
281- }
282241}
0 commit comments