Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public List<String> get() {
});

private final Map<String, String> availabilityZoneVsRegion = new ConcurrentHashMap<String, String>();
private final Map<String, String> parsedAzCache = new ConcurrentHashMap<String, String>();
private String[] regionsToFetch;

protected AbstractAzToRegionMapper(EurekaClientConfig clientConfig) {
Expand All @@ -53,6 +54,7 @@ public synchronized void setRegionsToFetch(String[] regionsToFetch) {
this.regionsToFetch = regionsToFetch;
logger.info("Fetching availability zone to region mapping for regions {}", (Object) regionsToFetch);
availabilityZoneVsRegion.clear();
parsedAzCache.clear();
for (String remoteRegion : regionsToFetch) {
Set<String> availabilityZones = getZonesForARegion(remoteRegion);
if (null == availabilityZones
Expand Down Expand Up @@ -83,6 +85,7 @@ public synchronized void setRegionsToFetch(String[] regionsToFetch) {
} else {
logger.info("Regions to fetch is null. Erasing older mapping if any.");
availabilityZoneVsRegion.clear();
parsedAzCache.clear();
this.regionsToFetch = EMPTY_STR_ARRAY;
}
}
Expand All @@ -96,9 +99,15 @@ public synchronized void setRegionsToFetch(String[] regionsToFetch) {

@Override
public String getRegionForAvailabilityZone(String availabilityZone) {
String region = availabilityZoneVsRegion.get(availabilityZone);
String region = parsedAzCache.get(availabilityZone);
if (null == region) {
return parseAzToGetRegion(availabilityZone);
region = availabilityZoneVsRegion.get(availabilityZone);
if (null == region) {
region = parseAzToGetRegion(availabilityZone);
}
if (region != null) {
parsedAzCache.put(availabilityZone, region);
}
}
return region;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1001,15 +1001,15 @@ private boolean fetchRegistry(boolean forceFullRegistryFetch) {
|| (!Strings.isNullOrEmpty(clientConfig.getRegistryRefreshSingleVipAddress()))
|| forceFullRegistryFetch
|| (applications == null)
|| (applications.getRegisteredApplications().size() == 0)
|| applications.isRegisteredApplicationsEmpty()
|| (applications.getVersion() == -1)) //Client application does not have latest library supporting delta
{
logger.info("Disable delta property : {}", clientConfig.shouldDisableDelta());
logger.info("Single vip registry refresh property : {}", clientConfig.getRegistryRefreshSingleVipAddress());
logger.info("Force full registry fetch : {}", forceFullRegistryFetch);
logger.info("Application is null : {}", (applications == null));
logger.info("Registered Applications size is zero : {}",
(applications.getRegisteredApplications().size() == 0));
applications.isRegisteredApplicationsEmpty());
logger.info("Application version is -1: {}", (applications.getVersion() == -1));
getAndStoreFullRegistry();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,15 @@ protected void autoMarshalEligible(Object o, JsonGenerator jgen) {
public static class InstanceInfoDeserializer extends JsonDeserializer<InstanceInfo> {
private static char[] BUF_AT_CLASS = "@class".toCharArray();

/** Extract uppercase from current JsonParser cursor. Avoids lambda capture. */
private static String toUpperCase(JsonParser jp) {
try {
return jp.getText().toUpperCase();
} catch (IOException e) {
throw new RuntimeJsonMappingException(e.getMessage());
}
}

enum InstanceInfoField {
HOSTNAME(ELEM_HOST),
INSTANCE_ID(ELEM_INSTANCE_ID),
Expand Down Expand Up @@ -515,14 +524,7 @@ public InstanceInfo deserialize(JsonParser jp, DeserializationContext context) t
break;
case APP:
builder.setAppNameForDeser(
intern.apply(jp, CacheScope.APPLICATION_SCOPE,
()->{
try {
return jp.getText().toUpperCase();
} catch (IOException e) {
throw new RuntimeJsonMappingException(e.getMessage());
}
}));
intern.apply(jp, CacheScope.APPLICATION_SCOPE, InstanceInfoDeserializer::toUpperCase));
break;
case IP:
builder.setIPAddr(intern.apply(jp));
Expand Down Expand Up @@ -590,14 +592,8 @@ public InstanceInfo deserialize(JsonParser jp, DeserializationContext context) t
builder.setHealthCheckUrlsForDeser(null, intern.apply(jp.getText()));
break;
case APPGROUPNAME:
builder.setAppGroupNameForDeser(intern.apply(jp, CacheScope.GLOBAL_SCOPE,
()->{
try {
return jp.getText().toUpperCase();
} catch (IOException e) {
throw new RuntimeJsonMappingException(e.getMessage());
}
}));
builder.setAppGroupNameForDeser(
intern.apply(jp, CacheScope.GLOBAL_SCOPE, InstanceInfoDeserializer::toUpperCase));
break;
case HOMEPAGEURL:
builder.setHomePageUrlForDeser(intern.apply(jp.getText()));
Expand Down Expand Up @@ -638,7 +634,9 @@ public InstanceInfo deserialize(JsonParser jp, DeserializationContext context) t
String key = intern.apply(jp, CacheScope.GLOBAL_SCOPE);
jsonToken = jp.nextToken();
String value = intern.apply(jp, CacheScope.APPLICATION_SCOPE );
metadataMap = Optional.ofNullable(metadataMap).orElseGet(METADATA_MAP_SUPPLIER);
if (metadataMap == null) {
metadataMap = METADATA_MAP_SUPPLIER.get();
}
metadataMap.put(key, value);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
Expand Down Expand Up @@ -135,7 +136,11 @@ public void removeInstance(InstanceInfo i) {
*/
@JsonProperty("instance")
public List<InstanceInfo> getInstances() {
return Optional.ofNullable(shuffledInstances.get()).orElseGet(this::getInstancesAsIsFromEureka);
List<InstanceInfo> instances = shuffledInstances.get();
if (instances == null) {
instances = this.getInstancesAsIsFromEureka();
}
return instances;
}

/**
Expand All @@ -152,6 +157,18 @@ public List<InstanceInfo> getInstancesAsIsFromEureka() {
}
}

/**
* Iterate over instances without creating a defensive copy.
* Package-private to avoid exposing unsynchronized iteration to external callers.
* Callers should be sure that this is a quick iteration.
*/
void forEachInstance(Consumer<InstanceInfo> consumer) {
synchronized (instances) {
for (InstanceInfo info : instances) {
consumer.accept(info);
}
}
}

/**
* Get the instance info that matches the given id.
Expand Down
Loading