add ServerSets
This commit is contained in:
parent
4bb8f6a51f
commit
1bf4bfc8a6
1 changed files with 79 additions and 6 deletions
|
@ -132,21 +132,30 @@ public final class Capability {
|
||||||
return new LocalClient();
|
return new LocalClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class LocalClient implements ClientHook {
|
ClientHook makeLocalClient(CapabilityServerSetBase capServerSet) {
|
||||||
|
return new LocalClient(capServerSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final class LocalClient implements ClientHook {
|
||||||
private final CompletableFuture<java.lang.Void> resolveTask;
|
private final CompletableFuture<java.lang.Void> resolveTask;
|
||||||
private ClientHook resolved;
|
private ClientHook resolved;
|
||||||
private boolean blocked = false;
|
private boolean blocked = false;
|
||||||
private Exception brokenException;
|
private Exception brokenException;
|
||||||
|
private final CapabilityServerSetBase capServerSet;
|
||||||
|
|
||||||
LocalClient() {
|
LocalClient() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalClient(CapabilityServerSetBase capServerSet) {
|
||||||
Server.this.hook = this;
|
Server.this.hook = this;
|
||||||
|
this.capServerSet = capServerSet;
|
||||||
|
|
||||||
var resolver = shortenPath();
|
var resolver = shortenPath();
|
||||||
this.resolveTask = resolver == null
|
this.resolveTask = resolver != null
|
||||||
? CompletableFuture.completedFuture(null)
|
? resolver.thenAccept(client -> this.resolved = client.getHook())
|
||||||
: resolver.thenAccept(client -> {
|
: null;
|
||||||
this.resolved = client.hook;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -211,6 +220,17 @@ public final class Capability {
|
||||||
return result.getPromise();
|
return result.getPromise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Server> getLocalServer(CapabilityServerSetBase capServerSet) {
|
||||||
|
if (this.capServerSet == capServerSet) {
|
||||||
|
if (this.blocked) {
|
||||||
|
assert false: "Blocked local server not implemented";
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompletableFuture.completedFuture(Server.this);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Client> shortenPath() {
|
public CompletableFuture<Client> shortenPath() {
|
||||||
|
@ -518,4 +538,57 @@ public final class Capability {
|
||||||
return this.promiseForClientResolution.copy();
|
return this.promiseForClientResolution.copy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class CapabilityServerSetBase {
|
||||||
|
|
||||||
|
ClientHook addInternal(Server server) {
|
||||||
|
return server.makeLocalClient(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<Server> getLocalServerInternal(ClientHook hook) {
|
||||||
|
for (;;) {
|
||||||
|
var next = hook.getResolved();
|
||||||
|
if (next != null) {
|
||||||
|
hook = next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hook.getBrand() == Server.BRAND) {
|
||||||
|
var promise = ((Server.LocalClient)hook).getLocalServer(this);
|
||||||
|
if (promise != null) {
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The capability isn't part of this set.
|
||||||
|
var resolver = hook.whenMoreResolved();
|
||||||
|
if (resolver != null) {
|
||||||
|
// This hook is an unresolved promise. It might resolve eventually to a local server, so wait
|
||||||
|
// for it.
|
||||||
|
return resolver.thenCompose(this::getLocalServerInternal);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Cap is settled, so it definitely will never resolve to a member of this set.
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CapabilityServerSet<T extends Capability.Server> extends CapabilityServerSetBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new capability Client for the given Server and also add this server to the set.
|
||||||
|
*/
|
||||||
|
<U extends Capability.Client> U add(Capability.Factory<U> factory, T server) {
|
||||||
|
var hook = this.addInternal(server);
|
||||||
|
return factory.newClient(hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompletableFuture<T> getLocalServer(Client client) {
|
||||||
|
return this.getLocalServerInternal(client.getHook())
|
||||||
|
.thenApply(server -> (T)server);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue