Skip to content

Commit 656ed73

Browse files
This feels a bit better
1 parent 409e176 commit 656ed73

File tree

6 files changed

+101
-154
lines changed

6 files changed

+101
-154
lines changed

servicetalk-client-api/src/main/java/io/servicetalk/client/api/DefaultMetadata.java

Lines changed: 0 additions & 73 deletions
This file was deleted.

servicetalk-client-api/src/main/java/io/servicetalk/client/api/Metadata.java

Lines changed: 0 additions & 55 deletions
This file was deleted.

servicetalk-client-api/src/main/java/io/servicetalk/client/api/MetadataKeys.java

Lines changed: 0 additions & 12 deletions
This file was deleted.

servicetalk-client-api/src/main/java/io/servicetalk/client/api/ServiceDiscovererEvent.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616
package io.servicetalk.client.api;
1717

1818
import java.util.Locale;
19+
import java.util.Map;
1920

2021
/**
2122
* Notification from the Service Discovery system that availability for an address has changed.
2223
* @param <ResolvedAddress> the type of address after resolution.
2324
*/
2425
public interface ServiceDiscovererEvent<ResolvedAddress> {
26+
2527
/**
2628
* Get the resolved address which is the subject of this event.
2729
* <p>
@@ -40,17 +42,12 @@ public interface ServiceDiscovererEvent<ResolvedAddress> {
4042
Status status();
4143

4244
/**
43-
* Meta-data associated with the specified address.
44-
* <p>
45-
* Metadata is data that is not strictly necessary for load balancing purposes but can be useful for making more
46-
* intelligent decisions. As described in {@link #address()}, updates to an addresses meta-data can be accomplished
47-
* by sending another {@link ServiceDiscovererEvent} with the same address and {@link Status} but with different
48-
* metadata. This also means that updates to status must also propagate the desired meta-data state or the empty
49-
* meta-data state is assumed.
50-
* @return
45+
* The raw meta-data associated with this ServiceDiscovererEvent.
46+
* Note: the result will be an unmodifiable collection.
47+
* @return the raw meta-data associated with this ServiceDiscovererEvent.
5148
*/
52-
default Metadata metadata() {
53-
return DefaultMetadata.EMPTY_METADATA;
49+
default Map<String, Object> metadata() {
50+
return ServiceDiscovererMetadata.EMPTY_MAP;
5451
}
5552

5653
/**
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package io.servicetalk.client.api;
2+
3+
import java.util.Collections;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
import static java.util.Objects.requireNonNull;
8+
9+
/**
10+
* Utilities helpful for extracting meta-data from {@link ServiceDiscovererEvent}s.
11+
*/
12+
public final class ServiceDiscovererMetadata {
13+
14+
public static final Map<String, Object> EMPTY_MAP = Collections.unmodifiableMap(new HashMap<>(0));
15+
16+
/**
17+
* Metadata that describes the relative weight of an endpoint.
18+
*/
19+
public static final Key<Double> WEIGHT = new ServiceDiscovererMetadata.Key<>(Double.class, "endpoint.weight", 1.0);
20+
21+
/**
22+
* Metadata describing the priority class of an endpoint.
23+
*/
24+
public static final Key<Integer> PRIORITY = new ServiceDiscovererMetadata.Key<>(
25+
Integer.class, "endpoint.priority", 0);
26+
27+
/**
28+
* An extractor of meta-data to user with {@link ServiceDiscovererEvent} instances.
29+
*
30+
* A {@link ServiceDiscovererEvent} can carry additional metadata, but this data is not type safe. The key type
31+
* exists to provide a uniform way to define meta-data extractors that can properly extract and cast meta-data
32+
* while also providing a default.
33+
* @param <T> the expected type of the meta-data.
34+
*/
35+
public static final class Key<T> {
36+
37+
private final Class<T> clazz;
38+
private final String name;
39+
private final T defaultValue;
40+
41+
public Key(final Class<T> clazz, final String name, final T defaultValue) {
42+
this.clazz = requireNonNull(clazz, "clazz");
43+
this.name = requireNonNull(name, "name");
44+
this.defaultValue = requireNonNull(defaultValue, "defaultValue");
45+
}
46+
47+
public String name() {
48+
return name;
49+
}
50+
51+
public Class<T> clazz() {
52+
return clazz;
53+
}
54+
55+
public <T> boolean exists(ServiceDiscovererEvent<?> event) {
56+
return event.metadata().containsKey(name);
57+
}
58+
59+
public T getValue(ServiceDiscovererEvent<?> event) {
60+
Object result = event.metadata().get(name);
61+
if (clazz.isInstance(result)) {
62+
return (T) result;
63+
} else {
64+
return defaultValue;
65+
}
66+
}
67+
68+
@Override
69+
public int hashCode() {
70+
return name.hashCode();
71+
}
72+
73+
@Override
74+
public boolean equals(Object obj) {
75+
if (obj == null || obj.getClass() != Key.class) {
76+
return false;
77+
}
78+
Key<?> other = (Key<?>) obj;
79+
return other.clazz.equals(clazz) && other.name.equals(name);
80+
}
81+
82+
@Override
83+
public String toString() {
84+
return "Key<" + clazz.getName() + ">(" + name + ", " + defaultValue + ")";
85+
}
86+
}
87+
88+
private ServiceDiscovererMetadata() {
89+
// no instances.
90+
}
91+
}

servicetalk-loadbalancer-experimental/src/main/java/io/servicetalk/loadbalancer/DefaultLoadBalancer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import io.servicetalk.client.api.ConnectionFactory;
1919
import io.servicetalk.client.api.LoadBalancedConnection;
20-
import io.servicetalk.client.api.MetadataKeys;
2120
import io.servicetalk.client.api.NoActiveHostException;
2221
import io.servicetalk.client.api.NoAvailableHostException;
2322
import io.servicetalk.client.api.ServiceDiscovererEvent;
@@ -53,7 +52,7 @@
5352

5453
import static io.servicetalk.client.api.LoadBalancerReadyEvent.LOAD_BALANCER_NOT_READY_EVENT;
5554
import static io.servicetalk.client.api.LoadBalancerReadyEvent.LOAD_BALANCER_READY_EVENT;
56-
import static io.servicetalk.client.api.MetadataKeys.WEIGHT;
55+
import static io.servicetalk.client.api.ServiceDiscovererMetadata.WEIGHT;
5756
import static io.servicetalk.client.api.ServiceDiscovererEvent.Status.AVAILABLE;
5857
import static io.servicetalk.client.api.ServiceDiscovererEvent.Status.EXPIRED;
5958
import static io.servicetalk.client.api.ServiceDiscovererEvent.Status.UNAVAILABLE;
@@ -311,7 +310,7 @@ private void sequentialOnNext(Collection<? extends ServiceDiscovererEvent<Resolv
311310
} else {
312311
// It's a new host, so the set changed.
313312
hostSetChanged = true;
314-
nextHosts.add(createHost(event.address(), event.metadata().get(WEIGHT)));
313+
nextHosts.add(createHost(event.address(), WEIGHT.getValue(event)));
315314
}
316315
} else if (EXPIRED.equals(event.status())) {
317316
if (!host.markExpired()) {
@@ -338,7 +337,7 @@ private void sequentialOnNext(Collection<? extends ServiceDiscovererEvent<Resolv
338337
if (AVAILABLE.equals(event.status())) {
339338
sendReadyEvent = true;
340339
hostSetChanged = true;
341-
nextHosts.add(createHost(event.address(), event.metadata().get(WEIGHT)));
340+
nextHosts.add(createHost(event.address(), WEIGHT.getValue(event)));
342341
}
343342
}
344343

0 commit comments

Comments
 (0)