diff options
3 files changed, 52 insertions, 5 deletions
diff --git a/container-core/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java b/container-core/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java index b203d7a9fb9..fef23f3cc27 100644 --- a/container-core/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java +++ b/container-core/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java @@ -46,7 +46,7 @@ public class ChainBuilder<T extends ChainedComponent> { public ChainBuilder(ComponentId id) { this.id = id; - allPhase = addPhase(new Phase("*", set("*"), Collections.<String>emptySet())); + allPhase = addPhase(new Phase("*", set("*"), Set.of())); } private Set<String> set(String... s) { diff --git a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java index dca83e8e556..623d11cc473 100644 --- a/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java +++ b/container-disc/src/main/java/com/yahoo/container/jdisc/ConfiguredApplication.java @@ -29,6 +29,7 @@ import com.yahoo.jdisc.application.DeactivatedContainer; import com.yahoo.jdisc.application.GuiceRepository; import com.yahoo.jdisc.application.OsgiFramework; import com.yahoo.jdisc.handler.RequestHandler; +import com.yahoo.jdisc.http.server.jetty.JettyHttpServer; import com.yahoo.jdisc.service.ClientProvider; import com.yahoo.jdisc.service.ServerProvider; import com.yahoo.jrt.Acceptor; @@ -41,6 +42,7 @@ import com.yahoo.jrt.Supervisor; import com.yahoo.jrt.Transport; import com.yahoo.jrt.slobrok.api.Register; import com.yahoo.jrt.slobrok.api.SlobrokList; +import com.yahoo.messagebus.jdisc.MbusServer; import com.yahoo.messagebus.network.rpc.SlobrokConfigSubscriber; import com.yahoo.net.HostName; import com.yahoo.security.tls.Capability; @@ -53,8 +55,10 @@ import java.security.Provider; import java.security.Security; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; @@ -377,20 +381,20 @@ public final class ConfiguredApplication implements Application { synchronized (monitor) { Set<ServerProvider> serversToClose = createIdentityHashSet(startedServers); serversToClose.removeAll(currentServers); - for (ServerProvider server : currentServers) { + for (ServerProvider server : ordered(currentServers, MbusServer.class, JettyHttpServer.class)) { if ( ! startedServers.contains(server) && server.isMultiplexed()) { server.start(); startedServers.add(server); } } - if (serversToClose.size() > 0) { + if ( ! serversToClose.isEmpty()) { log.info(String.format("Closing %d server instances", serversToClose.size())); - for (ServerProvider server : serversToClose) { + for (ServerProvider server : ordered(serversToClose, JettyHttpServer.class, MbusServer.class)) { server.close(); startedServers.remove(server); } } - for (ServerProvider server : currentServers) { + for (ServerProvider server : ordered(currentServers, MbusServer.class, JettyHttpServer.class)) { if ( ! startedServers.contains(server)) { server.start(); startedServers.add(server); @@ -525,6 +529,22 @@ public final class ConfiguredApplication implements Application { } } + /** Returns a list with the given elements, ordered by the enumerated classes, ordering more specific matches first. */ + @SafeVarargs + static <T> List<T> ordered(Collection<T> items, Class<? extends T>... order) { + List<T> ordered = new ArrayList<>(items); + ordered.sort(Comparator.comparingInt(item -> { + int best = order.length; + for (int i = 0; i < order.length; i++) { + if ( order[i].isInstance(item) + && ( best == order.length + || order[best].isAssignableFrom(order[i]))) best = i; + } + return best; + })); + return ordered; + } + private static <E> Set<E> createIdentityHashSet() { return Collections.newSetFromMap(new IdentityHashMap<>()); } diff --git a/container-disc/src/test/java/com/yahoo/container/jdisc/ConfiguredApplicationTest.java b/container-disc/src/test/java/com/yahoo/container/jdisc/ConfiguredApplicationTest.java new file mode 100644 index 00000000000..555d43f7697 --- /dev/null +++ b/container-disc/src/test/java/com/yahoo/container/jdisc/ConfiguredApplicationTest.java @@ -0,0 +1,27 @@ +package com.yahoo.container.jdisc; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static com.yahoo.container.jdisc.ConfiguredApplication.ordered; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ConfiguredApplicationTest { + + @Test + void testSorting() { + class A { @Override public String toString() { return getClass().getSimpleName(); } } + class B extends A { } + class C extends B { } + class D extends B { } + + A a = new A(), b = new B(), c = new C(), d = new D(), e = new D() { @Override public String toString() { return "E"; } }; + List<A> s = List.of(a, b, c, d, e); + assertEquals(List.of(a, b, c, d, e), ordered(s, A.class, B.class, C.class, D.class)); + assertEquals(List.of(d, e, c, b, a), ordered(s, D.class, C.class, B.class, A.class)); + assertEquals(List.of(e, c, a, b, d), ordered(s, e.getClass(), C.class, A.class)); + assertEquals(List.of(d, e, b, c, a), ordered(s, D.class, B.class)); + } + +} |