It is recommended that the operation of querying the shared variable first and then updating it be locked here, and this problem has not been reproduced after the lock is currently added. @OlgaMaciaszek Can you give a little advice?
void refreshInstanceInfo() {
applicationInfoManager.refreshDataCenterInfoIfRequired();
applicationInfoManager.refreshLeaseInfoIfRequired();
// need lock here
synchronized (applicationInfoManager) {
InstanceStatus status;
try {
status = getHealthCheckHandler().getStatus(instanceInfo.getStatus());
} catch (Exception e) {
logger.warn("Exception from healthcheckHandler.getStatus, setting status to DOWN", e);
status = InstanceStatus.DOWN;
}
if (null != status) {
applicationInfoManager.setInstanceStatus(status);
}
}
}
EurekaClientConfigurationRefresher & DiscoveryClient#refreshInstanceInfo concurrent execution
Describe the bug As we konw, when RefreshScopeRefreshedEvent published, service instances perform deregister and register actions. refer: EurekaDiscoveryClientConfiguration deregister and register will be call
ApplicationInfoManager#setInstanceStatus
to modifyInstanceStatus
.But, the DiscoveryClient will also be modified
InstanceStatus
by schedule task.So, EurekaClientConfigurationRefresher & DiscoveryClient#refreshInstanceInfo concurrent execution causes concurrency issues
Step1 deregister instance then modify
InstanceStatus
toDOWN
byEurekaClientConfigurationRefresher
Step2 get
InstanceStatus
frominstanceInfo
isDOWN
byDiscoveryClient#refreshInstanceInfo()
Step3 deregister instance then modify
InstanceStatus
toUP
byEurekaClientConfigurationRefresher
Step4 modify
InstanceStatus
toDOWN
byDiscoveryClient#refreshInstanceInfo()
If the execution order is as above, the service
InstanceStatus
changes toDOWN
.