add capability tail call test
This commit is contained in:
parent
1366e28fd5
commit
d3e639eaee
2 changed files with 44 additions and 2 deletions
|
@ -66,7 +66,7 @@ class TestExtendsImpl extends Test.TestExtends2.Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CapabilityTest {
|
public final class CapabilityTest {
|
||||||
|
|
||||||
@org.junit.Test
|
@org.junit.Test
|
||||||
public void testBasic() {
|
public void testBasic() {
|
||||||
|
@ -157,6 +157,40 @@ public class CapabilityTest {
|
||||||
Assert.assertEquals(1, chainedCallCount.value());
|
Assert.assertEquals(1, chainedCallCount.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void testTailCall() {
|
||||||
|
var calleeCallCount = new Counter();
|
||||||
|
var callerCallCount = new Counter();
|
||||||
|
var callee = new Test.TestTailCallee.Client(
|
||||||
|
new RpcTestUtil.TestTailCalleeImpl(calleeCallCount));
|
||||||
|
|
||||||
|
var caller = new Test.TestTailCaller.Client(
|
||||||
|
new RpcTestUtil.TestTailCallerImpl(callerCallCount));
|
||||||
|
|
||||||
|
var request = caller.fooRequest();
|
||||||
|
request.getParams().setI(456);
|
||||||
|
request.getParams().setCallee(callee);
|
||||||
|
|
||||||
|
var promise = request.send();
|
||||||
|
|
||||||
|
var dependentCall0 = promise.getC().getCallSequenceRequest().send();
|
||||||
|
|
||||||
|
var response = promise.join();
|
||||||
|
Assert.assertEquals(456, response.getI());
|
||||||
|
Assert.assertEquals(456, response.getI());
|
||||||
|
|
||||||
|
var dependentCall1 = promise.getC().getCallSequenceRequest().send();
|
||||||
|
|
||||||
|
var dependentCall2 = response.getC().getCallSequenceRequest().send();
|
||||||
|
|
||||||
|
Assert.assertEquals(0, dependentCall0.join().getN());
|
||||||
|
Assert.assertEquals(1, dependentCall1.join().getN());
|
||||||
|
Assert.assertEquals(2, dependentCall2.join().getN());
|
||||||
|
|
||||||
|
Assert.assertEquals(1, calleeCallCount.value());
|
||||||
|
Assert.assertEquals(1, callerCallCount.value());
|
||||||
|
}
|
||||||
|
|
||||||
class TestThisCap extends Test.TestInterface.Server {
|
class TestThisCap extends Test.TestInterface.Server {
|
||||||
|
|
||||||
Counter counter;
|
Counter counter;
|
||||||
|
|
|
@ -185,10 +185,18 @@ public final class Capability {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't want to actually dispatch the call synchronously, because we don't want the callee
|
||||||
|
// to have any side effects before the promise is returned to the caller. This helps avoid
|
||||||
|
// race conditions.
|
||||||
|
//
|
||||||
|
// So, we do an evalLater() here.
|
||||||
|
//
|
||||||
|
// Note also that QueuedClient depends on this evalLater() to ensure that pipelined calls don't
|
||||||
|
// complete before 'whenMoreResolved()' promises resolve.
|
||||||
|
// TODO fix the above comment! we don't have the option of evalLater (yes)
|
||||||
var promise = this.whenResolved().thenCompose(
|
var promise = this.whenResolved().thenCompose(
|
||||||
void_ -> this.callInternal(interfaceId, methodId, ctx));
|
void_ -> this.callInternal(interfaceId, methodId, ctx));
|
||||||
|
|
||||||
|
|
||||||
var pipelinePromise = promise.thenApply(x -> {
|
var pipelinePromise = promise.thenApply(x -> {
|
||||||
ctx.releaseParams();
|
ctx.releaseParams();
|
||||||
return (PipelineHook)new LocalPipeline(ctx);
|
return (PipelineHook)new LocalPipeline(ctx);
|
||||||
|
|
Loading…
Reference in a new issue