3131
3232import java .lang .invoke .MethodHandle ;
3333import java .lang .invoke .MethodHandles ;
34- import java .lang .invoke .MethodType ;
35- import java .lang .invoke .WrongMethodTypeException ;
36- import java .lang .reflect .Constructor ;
3734import java .lang .reflect .Field ;
38- import java .lang .reflect .InvocationTargetException ;
3935import java .lang .reflect .Method ;
4036import java .util .*;
4137import java .util .concurrent .ConcurrentHashMap ;
@@ -55,13 +51,6 @@ public class ApimlInstanceRegistry extends InstanceRegistry {
5551
5652 private static final String EXCEPTION_MESSAGE = "Implementation of InstanceRegistry changed, please verify fix of order sending events" ;
5753
58- private MethodHandle handleRegistrationMethod ;
59- private MethodHandle handlerResolveInstanceLeaseDurationMethod ;
60- private MethodHandle handleCancellationMethod ;
61-
62- private MethodHandle register2ArgsMethodHandle ;
63- private MethodHandle register3ArgsMethodHandle ;
64- private MethodHandle cancelMethodHandle ;
6554 private MethodHandle replicateToPeersMethodHandle ;
6655
6756 private final ApplicationContext appCntx ;
@@ -70,6 +59,8 @@ public class ApimlInstanceRegistry extends InstanceRegistry {
7059 private ConcurrentHashMap <String , Map <String , Lease <InstanceInfo >>> registry ;
7160 private Set <String > staticRegistrationIds = Collections .synchronizedSet (new HashSet <>());
7261
62+ private static final ThreadLocal <Integer > RENEW_CORRECTION = new ThreadLocal <>();
63+
7364 public ApimlInstanceRegistry (
7465 EurekaServerConfig serverConfig ,
7566 EurekaClientConfig clientConfig ,
@@ -96,79 +87,29 @@ public ApimlInstanceRegistry(
9687 */
9788 private void init () {
9889 try {
99- Method registrationMethod =
100- InstanceRegistry .class .getDeclaredMethod ("handleRegistration" ,
101- InstanceInfo .class , int .class , boolean .class
102- );
103- registrationMethod .setAccessible (true );
104- handleRegistrationMethod = MethodHandles .lookup ().unreflect (registrationMethod );
105-
106- Method cancelationMethod =
107- InstanceRegistry .class .getDeclaredMethod ("handleCancelation" ,
108- String .class , String .class , boolean .class
109- );
110- cancelationMethod .setAccessible (true );
111- handleCancellationMethod = MethodHandles .lookup ().unreflect (cancelationMethod );
112-
113- Method resolveInstanceLeaseDurationMethod =
114- InstanceRegistry .class .getDeclaredMethod ("resolveInstanceLeaseDuration" ,
115- InstanceInfo .class
116- );
117- resolveInstanceLeaseDurationMethod .setAccessible (true );
118- handlerResolveInstanceLeaseDurationMethod = MethodHandles .lookup ().unreflect (resolveInstanceLeaseDurationMethod );
119-
120- Constructor <MethodHandles .Lookup > lookupConstructor = MethodHandles .Lookup .class .getDeclaredConstructor (Class .class );
121- lookupConstructor .setAccessible (true );
122- MethodHandles .Lookup lookup = lookupConstructor .newInstance (PeerAwareInstanceRegistryImpl .class );
123-
124- register2ArgsMethodHandle =
125- lookup .findSpecial (
126- PeerAwareInstanceRegistryImpl .class ,
127- "register" ,
128- MethodType .methodType (void .class , InstanceInfo .class , boolean .class ),
129- PeerAwareInstanceRegistryImpl .class
130- );
131-
132- cancelMethodHandle =
133- lookup .findSpecial (
134- PeerAwareInstanceRegistryImpl .class ,
135- "cancel" ,
136- MethodType .methodType (boolean .class , String .class , String .class , boolean .class ),
137- PeerAwareInstanceRegistryImpl .class
138- );
139-
140- lookup = lookupConstructor .newInstance (AbstractInstanceRegistry .class );
141-
142- register3ArgsMethodHandle =
143- lookup .findSpecial (
144- AbstractInstanceRegistry .class ,
145- "register" ,
146- MethodType .methodType (void .class , InstanceInfo .class , int .class , boolean .class ),
147- AbstractInstanceRegistry .class
148- );
14990 Field registryField = AbstractInstanceRegistry .class .getDeclaredField ("registry" );
15091 registryField .setAccessible (true );
15192 this .registry = (ConcurrentHashMap <String , Map <String , Lease <InstanceInfo >>>) registryField .get (this );
15293
15394 Method replicateToPeers = PeerAwareInstanceRegistryImpl .class .getDeclaredMethod ("replicateToPeers" , Action .class , String .class , String .class , InstanceInfo .class , InstanceStatus .class , boolean .class );
15495 replicateToPeers .setAccessible (true );
155-
15696 replicateToPeersMethodHandle = MethodHandles .lookup ().unreflect (replicateToPeers );
157- } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e ) {
97+ } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException e ) {
15898 throw new IllegalArgumentException (EXCEPTION_MESSAGE , e );
15999 }
160100 }
161101
162- protected int resolveInstanceLeaseDurationRewritten (final InstanceInfo info ) {
163- try {
164- return (int ) handlerResolveInstanceLeaseDurationMethod .invokeWithArguments (this , info );
165- } catch (ClassCastException | WrongMethodTypeException e ) {
166- throw new IllegalArgumentException (EXCEPTION_MESSAGE , e );
167- } catch (RuntimeException re ) {
168- throw re ;
169- } catch (Throwable t ) {
170- throw new IllegalArgumentException (EXCEPTION_MESSAGE , t );
102+ @ Override
103+ protected void updateRenewsPerMinThreshold () {
104+ Integer correction = RENEW_CORRECTION .get ();
105+ if (correction != null ) {
106+ synchronized (lock ) {
107+ this .expectedNumberOfClientsSendingRenews += correction ;
108+ }
109+ RENEW_CORRECTION .remove ();
171110 }
111+
112+ super .updateRenewsPerMinThreshold ();
172113 }
173114
174115 public void peerAwareHeartbeat (InstanceInfo instanceInfo ) {
@@ -191,19 +132,17 @@ public void registerStatically(InstanceInfo instanceInfo, boolean isReplication,
191132 // the maximum lease duration time (Eureka bug: overflow of int during conversion to ms)
192133 int leaseDuration = Integer .MAX_VALUE / 1000 ;
193134
194- // temporary register (do not increase count of service to avoid threshold)
195- synchronized (lock ) {
196- int backup = expectedNumberOfClientsSendingRenews ;
197- try {
198- register (instanceInfo , leaseDuration , isReplication );
199- if (peerReplicate ) {
200- replicateToPeersMethodHandle .invokeWithArguments (this , Action .Register , instanceInfo .getAppName (), instanceInfo .getId (), instanceInfo , null , isReplication );
201- }
202- } catch (Throwable e ) {
203- throw new IllegalStateException (EXCEPTION_MESSAGE , e );
204- } finally {
205- expectedNumberOfClientsSendingRenews = backup ;
135+ try {
136+ // temporary register (do not increase count of service to avoid threshold)
137+ RENEW_CORRECTION .set (-1 );
138+ register (instanceInfo , leaseDuration , isReplication );
139+ if (peerReplicate ) {
140+ replicateToPeersMethodHandle .invokeWithArguments (this , Action .Register , instanceInfo .getAppName (), instanceInfo .getId (), instanceInfo , null , isReplication );
206141 }
142+ } catch (Throwable e ) {
143+ throw new IllegalStateException (EXCEPTION_MESSAGE , e );
144+ } finally {
145+ RENEW_CORRECTION .remove ();
207146 }
208147
209148 // register lease plan to never expired
@@ -229,34 +168,18 @@ public boolean isExpired(long additionalLeaseMs) {
229168 */
230169 @ Override
231170 public void register (InstanceInfo info , int leaseDuration , boolean isReplication ) {
232- validateInstanceInfo (info );
233- info = changeServiceId (info );
234- try {
235- register3ArgsMethodHandle .invokeWithArguments (this , info , leaseDuration , isReplication );
236- handleRegistrationMethod .invokeWithArguments (this , info , leaseDuration , isReplication );
237- } catch (ClassCastException | WrongMethodTypeException e ) {
238- throw new IllegalArgumentException (EXCEPTION_MESSAGE , e );
239- } catch (RuntimeException re ) {
240- throw re ;
241- } catch (Throwable t ) {
242- throw new IllegalArgumentException (EXCEPTION_MESSAGE , t );
243- }
171+ validateInstanceInfo (info );
172+ info = changeServiceId (info );
173+
174+ super .register (info , leaseDuration , isReplication );
244175 }
245176
246177 @ Override
247178 public void register (InstanceInfo info , final boolean isReplication ) {
248- validateInstanceInfo (info );
249- info = changeServiceId (info );
250- try {
251- register2ArgsMethodHandle .invokeWithArguments (this , info , isReplication );
252- handleRegistrationMethod .invokeWithArguments (this , info , resolveInstanceLeaseDurationRewritten (info ), isReplication );
253- } catch (ClassCastException | WrongMethodTypeException e ) {
254- throw new IllegalArgumentException (EXCEPTION_MESSAGE , e );
255- } catch (RuntimeException re ) {
256- throw re ;
257- } catch (Throwable t ) {
258- throw new IllegalArgumentException (EXCEPTION_MESSAGE , t );
259- }
179+ validateInstanceInfo (info );
180+ info = changeServiceId (info );
181+
182+ super .register (info , isReplication );
260183 }
261184
262185 /**
@@ -309,25 +232,16 @@ public boolean isRegisterable(InstanceInfo instanceInfo) {
309232
310233 @ Override
311234 public boolean cancel (String appName , String serverId , boolean isReplication ) {
312- synchronized (lock ) {
313- int backup = expectedNumberOfClientsSendingRenews ;
314- try {
315- String [] updatedValues = replaceValues (appName , serverId );
316- final boolean out = (boolean ) cancelMethodHandle .invokeWithArguments (this , updatedValues [0 ], updatedValues [1 ], isReplication );
317- handleCancellationMethod .invokeWithArguments (this , updatedValues [0 ], updatedValues [1 ], isReplication );
318- return out ;
319- } catch (ClassCastException | WrongMethodTypeException e ) {
320- throw new IllegalArgumentException (EXCEPTION_MESSAGE , e );
321- } catch (RuntimeException re ) {
322- throw re ;
323- } catch (Throwable t ) {
324- throw new IllegalArgumentException (EXCEPTION_MESSAGE , t );
325- } finally {
326- if (staticRegistrationIds .removeAll (Optional .ofNullable (registry .get (appName )).orElse (Collections .emptyMap ()).keySet ())) {
327- // do not change count of instances if it was registered statically
328- expectedNumberOfClientsSendingRenews = backup ;
329- }
235+ try {
236+ String [] updatedValues = replaceValues (appName , serverId );
237+
238+ if (staticRegistrationIds .removeAll (Optional .ofNullable (registry .get (appName )).orElse (Collections .emptyMap ()).keySet ())) {
239+ // do not change count of instances if it was registered statically
240+ RENEW_CORRECTION .set (1 );
330241 }
242+ return super .cancel (updatedValues [0 ], updatedValues [1 ], isReplication );
243+ } finally {
244+ RENEW_CORRECTION .remove ();
331245 }
332246 }
333247
0 commit comments