Revert "resolve PromiseClient requests in order"
This reverts commit d526eca4b9
.
This commit is contained in:
parent
3513db0588
commit
054e4efdb1
1 changed files with 35 additions and 16 deletions
|
@ -1509,33 +1509,43 @@ final class RpcState<VatId> {
|
||||||
private class RpcPipeline implements PipelineHook {
|
private class RpcPipeline implements PipelineHook {
|
||||||
|
|
||||||
private final QuestionRef questionRef;
|
private final QuestionRef questionRef;
|
||||||
|
private PipelineState state = PipelineState.WAITING;
|
||||||
|
private RpcResponse resolved;
|
||||||
|
private Throwable broken;
|
||||||
|
|
||||||
final HashMap<List<PipelineOp>, ClientHook> clientMap = new HashMap<>();
|
final HashMap<List<PipelineOp>, ClientHook> clientMap = new HashMap<>();
|
||||||
final CompletableFuture<RpcResponse> redirectLater;
|
final CompletableFuture<RpcResponse> redirectLater;
|
||||||
|
final CompletableFuture<java.lang.Void> resolveSelf;
|
||||||
|
|
||||||
RpcPipeline(QuestionRef questionRef,
|
RpcPipeline(QuestionRef questionRef,
|
||||||
CompletableFuture<RpcResponse> redirectLater) {
|
CompletableFuture<RpcResponse> redirectLater) {
|
||||||
this.questionRef = questionRef;
|
this.questionRef = questionRef;
|
||||||
assert redirectLater != null;
|
assert redirectLater != null;
|
||||||
this.redirectLater = redirectLater;
|
this.redirectLater = redirectLater;
|
||||||
|
this.resolveSelf = this.redirectLater
|
||||||
|
.thenAccept(response -> {
|
||||||
|
this.state = PipelineState.RESOLVED;
|
||||||
|
this.resolved = response;
|
||||||
|
})
|
||||||
|
.exceptionally(exc -> {
|
||||||
|
this.state = PipelineState.BROKEN;
|
||||||
|
this.broken = exc;
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
RpcPipeline(QuestionRef questionRef) {
|
RpcPipeline(QuestionRef questionRef) {
|
||||||
this(questionRef, null);
|
this(questionRef, null);
|
||||||
// never resolves
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientHook getPipelinedCap(PipelineOp[] ops) {
|
public ClientHook getPipelinedCap(PipelineOp[] ops) {
|
||||||
// We differ from the C++ implementation here.
|
|
||||||
// Previously, we would just store and return the resolved client, but this
|
|
||||||
// could cause tail calls to execute out of order.
|
|
||||||
// So instead we always chain resolution on the redirectLater promise, which
|
|
||||||
// ensures that each call initiated from this PromiseClient is executed in order.
|
|
||||||
|
|
||||||
// TODO avoid conversion to/from ArrayList?
|
// TODO avoid conversion to/from ArrayList?
|
||||||
var key = new ArrayList<>(Arrays.asList(ops));
|
var key = new ArrayList<>(Arrays.asList(ops));
|
||||||
return this.clientMap.computeIfAbsent(key, k -> {
|
|
||||||
|
var hook = this.clientMap.computeIfAbsent(key, k -> {
|
||||||
|
switch (state) {
|
||||||
|
case WAITING: {
|
||||||
var pipelineClient = new PipelineClient(this.questionRef, ops);
|
var pipelineClient = new PipelineClient(this.questionRef, ops);
|
||||||
if (this.redirectLater == null) {
|
if (this.redirectLater == null) {
|
||||||
// This pipeline will never get redirected, so just return the PipelineClient.
|
// This pipeline will never get redirected, so just return the PipelineClient.
|
||||||
|
@ -1545,7 +1555,16 @@ final class RpcState<VatId> {
|
||||||
var resolutionPromise = this.redirectLater.thenApply(
|
var resolutionPromise = this.redirectLater.thenApply(
|
||||||
response -> response.getResults().getPipelinedCap(ops));
|
response -> response.getResults().getPipelinedCap(ops));
|
||||||
return new PromiseClient(pipelineClient, resolutionPromise, null);
|
return new PromiseClient(pipelineClient, resolutionPromise, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
case RESOLVED:
|
||||||
|
return resolved.getResults().getPipelinedCap(ops);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Capability.newBrokenCap(broken);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
return hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue