diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java index b7de69ee..3b984421 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java @@ -175,20 +175,44 @@ public class AsyncEntryIntegrationTest { ContextUtil.exit(); } - TimeUnit.SECONDS.sleep(10); - testTreeCorrect(); + TimeUnit.SECONDS.sleep(15); + + testInvocationTreeCorrect(); } - private void testTreeCorrect() { + private void testInvocationTreeCorrect() { DefaultNode root = Constants.ROOT; - Set childListForRoot = root.getChildList(); - // TODO: check child tree + DefaultNode entranceNode = shouldHasChildFor(root, contextName); + DefaultNode testTopNode = shouldHasChildFor(entranceNode, "test-top"); + DefaultNode testAsyncNode = shouldHasChildFor(testTopNode, "test-async"); + shouldHasChildFor(testTopNode, "test-sync"); + shouldHasChildFor(testAsyncNode, "test-sync-in-async"); + DefaultNode anotherAsyncInAsyncNode = shouldHasChildFor(testAsyncNode, "test-another-async"); + shouldHasChildFor(anotherAsyncInAsyncNode, "test-another-in-async"); + } + + private DefaultNode shouldHasChildFor(DefaultNode root, String resourceName) { + Set nodeSet = root.getChildList(); + if (nodeSet == null || nodeSet.isEmpty()) { + fail("Child nodes should not be empty: " + root.getId().getName()); + } + for (Node node : nodeSet) { + if (node instanceof DefaultNode) { + DefaultNode dn = (DefaultNode)node; + if (dn.getId().getName().equals(resourceName)) { + return dn; + } + } + } + fail(String.format("The given node <%s> does not have child for resource <%s>", + root.getId().getName(), resourceName)); + return null; } @After public void shutdown() { pool.shutdownNow(); - ContextUtil.exit(); + ContextTestUtil.cleanUpContext(); } private void runAsync(Runnable f) { diff --git a/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/AsyncEntryDemo.java b/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/AsyncEntryDemo.java index d9f5c391..230e943d 100644 --- a/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/AsyncEntryDemo.java +++ b/sentinel-demo/sentinel-demo-basic/src/main/java/com/alibaba/csp/sentinel/demo/AsyncEntryDemo.java @@ -58,7 +58,9 @@ public class AsyncEntryDemo { ContextUtil.runOnContext(entry.getAsyncContext(), () -> { try { TimeUnit.SECONDS.sleep(2); + // Normal entry nested in asynchronous entry. anotherSyncInAsync(); + System.out.println("Async result: 666"); } catch (InterruptedException e) { // Ignore. @@ -115,12 +117,10 @@ public class AsyncEntryDemo { try { final AsyncEntry entry = SphU.asyncEntry("test-async-not-nested"); - CompletableFuture.runAsync(() -> { + this.invoke("abc", result -> { // If no nested entry later, we don't have to wrap in `ContextUtil.runOnContext()`. try { - TimeUnit.SECONDS.sleep(1); - } catch (InterruptedException ex) { - // Ignore. + // Here to handle the async result (without other entry). } finally { // Exit the async entry. entry.exit(); @@ -138,7 +138,7 @@ public class AsyncEntryDemo { final AsyncEntry entry = SphU.asyncEntry("test-async"); this.invoke("abc", resp -> { // The thread is different from original caller thread for async entry. - // So we need to wrap in the async context so that nested sync invocation entry + // So we need to wrap in the async context so that nested invocation entry // can be linked to the parent asynchronous entry. ContextUtil.runOnContext(entry.getAsyncContext(), () -> { try { @@ -149,7 +149,7 @@ public class AsyncEntryDemo { System.out.println(resp); - // Then we do a sync entry under current async context. + // Then we do a sync (normal) entry under current async context. fetchSyncInAsync(); } finally { // Exit the async entry. @@ -165,7 +165,7 @@ public class AsyncEntryDemo { } } - public static void main(String[] args) { + public static void main(String[] args) throws Exception { initFlowRule(); AsyncEntryDemo service = new AsyncEntryDemo(); @@ -195,6 +195,8 @@ public class AsyncEntryDemo { } ContextUtil.exit(); } + + TimeUnit.SECONDS.sleep(20); } private static void initFlowRule() {