-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement semaphore synchronization to prevent concurrent modificatio…issue#4094 #4301
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,6 @@ | |
import com.netflix.appinfo.HealthCheckHandler; | ||
import com.netflix.discovery.EurekaClient; | ||
import com.netflix.discovery.EurekaClientConfig; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.actuate.health.SimpleStatusAggregator; | ||
import org.springframework.boot.actuate.health.StatusAggregator; | ||
|
@@ -35,6 +34,8 @@ | |
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
import java.util.concurrent.Semaphore; | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add your full name with |
||
* @author Dave Syer | ||
* @author Spencer Gibb | ||
|
@@ -51,52 +52,100 @@ | |
@ConditionalOnBlockingDiscoveryEnabled | ||
public class EurekaDiscoveryClientConfiguration { | ||
|
||
@Bean | ||
@ConditionalOnMissingBean | ||
public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems you've changed formatting - as a result it shows as if you've modified all these lines of code. Please revert to our formatting (possibly a spaces/ tabs issue) so that it's clearly visible in the diff what code has been changed by you. |
||
return new EurekaDiscoveryClient(client, clientConfig); | ||
} | ||
|
||
@Configuration(proxyBeanMethods = false) | ||
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false) | ||
protected static class EurekaHealthCheckHandlerConfiguration { | ||
|
||
@Autowired(required = false) | ||
private StatusAggregator statusAggregator = new SimpleStatusAggregator(); | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(HealthCheckHandler.class) | ||
public EurekaHealthCheckHandler eurekaHealthCheckHandler() { | ||
return new EurekaHealthCheckHandler(this.statusAggregator); | ||
} | ||
|
||
} | ||
|
||
@Configuration(proxyBeanMethods = false) | ||
@ConditionalOnClass(RefreshScopeRefreshedEvent.class) | ||
protected static class EurekaClientConfigurationRefresher | ||
implements ApplicationListener<RefreshScopeRefreshedEvent> { | ||
|
||
@Autowired(required = false) | ||
private EurekaClient eurekaClient; | ||
|
||
@Autowired(required = false) | ||
private EurekaAutoServiceRegistration autoRegistration; | ||
|
||
public void onApplicationEvent(RefreshScopeRefreshedEvent event) { | ||
// This will force the creation of the EurekaClient bean if not already | ||
// created | ||
// to make sure the client will be re-registered after a refresh event | ||
if (eurekaClient != null) { | ||
eurekaClient.getApplications(); | ||
} | ||
if (autoRegistration != null) { | ||
// register in case meta data changed | ||
this.autoRegistration.stop(); | ||
this.autoRegistration.start(); | ||
} | ||
} | ||
|
||
} | ||
@Bean | ||
@ConditionalOnMissingBean | ||
public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) { | ||
return new EurekaDiscoveryClient(client, clientConfig); | ||
} | ||
|
||
@Configuration(proxyBeanMethods = false) | ||
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false) | ||
protected static class EurekaHealthCheckHandlerConfiguration { | ||
|
||
@Autowired(required = false) | ||
private StatusAggregator statusAggregator = new SimpleStatusAggregator(); | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(HealthCheckHandler.class) | ||
public EurekaHealthCheckHandler eurekaHealthCheckHandler() { | ||
return new EurekaHealthCheckHandler(this.statusAggregator); | ||
} | ||
|
||
} | ||
|
||
@Configuration(proxyBeanMethods = false) | ||
@ConditionalOnClass(RefreshScopeRefreshedEvent.class) | ||
protected static class EurekaClientConfigurationRefresher | ||
implements ApplicationListener<RefreshScopeRefreshedEvent> { | ||
|
||
private final Semaphore semaphore = new Semaphore(1); | ||
|
||
@Autowired(required = false) | ||
private EurekaClient eurekaClient; | ||
|
||
@Autowired(required = false) | ||
private EurekaAutoServiceRegistration autoRegistration; | ||
|
||
public void onApplicationEvent(RefreshScopeRefreshedEvent event) { | ||
try { | ||
semaphore.acquire(); | ||
if (eurekaClient != null) { | ||
eurekaClient.getApplications(); | ||
} | ||
if (autoRegistration != null) { | ||
// deregister instance | ||
this.autoRegistration.stop(); | ||
// register instance | ||
this.autoRegistration.start(); | ||
} | ||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
} finally { | ||
semaphore.release(); | ||
} | ||
} | ||
|
||
} | ||
|
||
@Configuration(proxyBeanMethods = false) | ||
protected static class DiscoveryClientConfiguration { | ||
|
||
private final Semaphore semaphore = new Semaphore(1); | ||
|
||
@Autowired | ||
private ApplicationInfoManager applicationInfoManager; | ||
|
||
@Autowired | ||
private HealthCheckHandler healthCheckHandler; | ||
|
||
@Autowired | ||
private InstanceInfo instanceInfo; | ||
|
||
void refreshInstanceInfo() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems this method is not ever used - please verify and finish up your changes, and then request another review. |
||
try { | ||
semaphore.acquire(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use binary semaphore rather than a ReentrantLock? |
||
applicationInfoManager.refreshDataCenterInfoIfRequired(); | ||
applicationInfoManager.refreshLeaseInfoIfRequired(); | ||
|
||
InstanceStatus status; | ||
try { | ||
// get instance status | ||
status = healthCheckHandler.getStatus(instanceInfo.getStatus()); | ||
} catch (Exception e) { | ||
logger.warn("Exception from healthcheckHandler.getStatus, setting status to DOWN", e); | ||
status = InstanceStatus.DOWN; | ||
} | ||
|
||
if (null != status) { | ||
// modify instance status | ||
applicationInfoManager.setInstanceStatus(status); | ||
} | ||
} catch (InterruptedException e) { | ||
Thread.currentThread().interrupt(); | ||
} finally { | ||
semaphore.release(); | ||
} | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the date in the license comment to
2013-2024
.