public void testSyncInvocationManyHandlers() throws Exception { sideEffects.set(""); CompletableFuture<Object> f = CompletableFuture.completedFuture(""); AsyncInterceptorChain chain = makeChainWithManyHandlers(f); CompletableFuture<Object> invokeFuture = chain.invokeAsync(newInvocationContext(), testCommand); assertHandlers(invokeFuture); }
public void testAsyncInvocationManyHandlers() throws Exception { sideEffects.set(""); CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = makeChainWithManyHandlers(f); CompletableFuture<Object> invokeFuture = chain.invokeAsync(newInvocationContext(), testCommand); f.complete(""); assertHandlers(invokeFuture); }
public void testAsyncInvocationManyHandlersAsyncException() throws Exception { sideEffects.set(""); CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = makeChainWithManyHandlers(f); CompletableFuture<Object> invokeFuture = chain.invokeAsync(newInvocationContext(), testCommand); f.completeExceptionally(new TestException("")); assertExceptionHandlers(invokeFuture); }
public void testAsyncStage() throws Exception { CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return asyncValue(f); } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f.complete("v1"); assertEquals("v1", invokeFuture.get(10, SECONDS)); }
public void testAsyncStageCompose() throws Exception { CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return invokeNextAndHandle(ctx, command, (rCtx, rCommand, rv, t) -> "v1"); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return asyncValue(f); } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f.complete("v2"); assertEquals("v1", invokeFuture.get(10, SECONDS)); }
public void testAsyncStageComposeAsyncStage() throws Exception { CompletableFuture<Object> f1 = new CompletableFuture<>(); CompletableFuture<Object> f2 = new CompletableFuture<>(); CompletableFuture<Object> f3 = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return invokeNextAndHandle(ctx, command, (rCtx, rCommand, rv, t) -> { InvocationSuccessFunction function = (rCtx1, rCommand1, rv1) -> asyncValue(f3); return asyncValue(f2).addCallback(rCtx, rCommand, function); }); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return asyncValue(f1); } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f1.complete("v1"); assertFalse(invokeFuture.isDone()); f2.complete("v2"); assertFalse(invokeFuture.isDone()); f3.complete("v3"); assertEquals("v3", invokeFuture.get(10, SECONDS)); }
public void testComposeAsync() throws Exception { CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return invokeNextAndHandle(ctx, command, (rCtx, rCommand, rv, t) -> asyncValue(f)); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return "v1"; } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f.complete("v2"); assertEquals("v2", invokeFuture.get(10, SECONDS)); }
public void testInvokeNextAsync() throws Exception { CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return asyncInvokeNext(ctx, command, f); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return "v1"; } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f.complete("v"); assertEquals("v1", invokeFuture.get(10, SECONDS)); }
public void testInvokeNextAsyncSubCommand() throws Exception { CompletableFuture<Object> f = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return asyncInvokeNext(ctx, testSubCommand, f); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return command instanceof LockControlCommand ? "subCommand" : "command"; } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); f.complete("v"); assertEquals("subCommand", invokeFuture.get(10, SECONDS)); }
public void testDeadlockWithAsyncStage() throws Exception { CompletableFuture<Object> f1 = new CompletableFuture<>(); CompletableFuture<Object> f2 = new CompletableFuture<>(); AsyncInterceptorChain chain = newInterceptorChain(new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { return invokeNextThenApply(ctx, command, (rCtx, rCommand, rv) -> rv + " " + awaitFuture(f2)); } }, new BaseAsyncInterceptor() { @Override public Object visitCommand(InvocationContext ctx, VisitableCommand command) throws Throwable { // Add a handler to force the return value to be a full AsyncInvocationStage InvocationSuccessFunction function = (rCtx, rCommand, rv) -> rv; return asyncValue(f1).addCallback(ctx, command, function); } }); InvocationContext context = newInvocationContext(); CompletableFuture<Object> invokeFuture = chain.invokeAsync(context, testCommand); assertFalse(invokeFuture.isDone()); Future<Boolean> fork = fork(() -> f1.complete("v1")); Thread.sleep(100); assertFalse(fork.isDone()); assertFalse(invokeFuture.isDone()); f2.complete("v2"); fork.get(10, SECONDS); assertEquals("v1 v2", invokeFuture.getNow(null)); }
public void testAsyncInvocationManyHandlersSyncException() throws Exception { sideEffects.set(""); CompletableFuture<Object> f = CompletableFutures.completedExceptionFuture(new TestException("")); AsyncInterceptorChain chain = makeChainWithManyHandlers(f); CompletableFuture<Object> invokeFuture = chain.invokeAsync(newInvocationContext(), testCommand); assertExceptionHandlers(invokeFuture); }