Repository: alibaba/Sentinel (Java)

Issue:
Remove the requirement of carrying args in entry.exit()
<!-- Here is for bug reports and feature requests ONLY! 

If you're looking for help, please check our mail list and the Gitter room.

Please try to use English to describe your issue, or at least provide a snippet of English translation.
-->

## Issue Description

Type: *enhancement*

### Describe what feature you want

Remove the requirement of carrying args in `entry.exit()`.

目前对于带参数的自定义埋点，`entry.exit()` 的时候需要也带上埋点的参数（比如 `entry.exit(arg1, arg2)`），这样使用起来不太方便。期望最终实现 exit 时不需要带上埋点的参数以及 batchCount。

### Describe your initial design (if present)

Hold args in `Entry` so that users don't need to carry args or argMap on `Entry` exit.



Discussion:

Patch:
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/AsyncEntry.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/AsyncEntry.java
index 98ccb85a22..b58ec7ba6a 100644
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/AsyncEntry.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/AsyncEntry.java
@@ -35,6 +35,10 @@ public class AsyncEntry extends CtEntry {
         super(resourceWrapper, chain, context);
     }
 
+    AsyncEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context, int count, Object[] args) {
+        super(resourceWrapper, chain, context, count, args);
+    }
+
     /**
      * Remove current entry from local context, but does not exit.
      */
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtEntry.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtEntry.java
index 6c62abe810..8f4ec250a8 100644
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtEntry.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtEntry.java
@@ -42,7 +42,11 @@ class CtEntry extends Entry {
     protected LinkedList<BiConsumer<Context, Entry>> exitHandlers;
 
     CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context) {
-        super(resourceWrapper);
+        this(resourceWrapper, chain, context, 1, OBJECTS0);
+    }
+
+    CtEntry(ResourceWrapper resourceWrapper, ProcessorSlot<Object> chain, Context context, int count, Object[] args) {
+        super(resourceWrapper, count, args);
         this.chain = chain;
         this.context = context;
 
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java
index 84ebf17dcb..88a76f750d 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/CtSph.java
@@ -86,7 +86,7 @@ private AsyncEntry asyncEntryWithPriorityInternal(ResourceWrapper resourceWrappe
             return asyncEntryWithNoChain(resourceWrapper, context);
         }
 
-        AsyncEntry asyncEntry = new AsyncEntry(resourceWrapper, chain, context);
+        AsyncEntry asyncEntry = new AsyncEntry(resourceWrapper, chain, context, count, args);
         try {
             chain.entry(context, resourceWrapper, null, count, prioritized, args);
             // Initiate the async context only when the entry successfully passed the slot chain.
@@ -143,7 +143,7 @@ private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, bool
             return new CtEntry(resourceWrapper, null, context);
         }
 
-        Entry e = new CtEntry(resourceWrapper, chain, context);
+        Entry e = new CtEntry(resourceWrapper, chain, context, count, args);
         try {
             chain.entry(context, resourceWrapper, null, count, prioritized, args);
         } catch (BlockException e1) {
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java
index c3114821c3..857e6e9b94 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Entry.java
@@ -53,7 +53,7 @@
  */
 public abstract class Entry implements AutoCloseable {
 
-    private static final Object[] OBJECTS0 = new Object[0];
+    protected static final Object[] OBJECTS0 = new Object[0];
 
     private final long createTimestamp;
     private long completeTimestamp;
@@ -69,9 +69,19 @@ public abstract class Entry implements AutoCloseable {
 
     protected final ResourceWrapper resourceWrapper;
 
+    protected final int count;
+
+    protected final Object[] args;
+
     public Entry(ResourceWrapper resourceWrapper) {
+        this(resourceWrapper, 1, OBJECTS0);
+    }
+
+    public Entry(ResourceWrapper resourceWrapper, int count, Object[] args) {
         this.resourceWrapper = resourceWrapper;
         this.createTimestamp = TimeUtil.currentTimeMillis();
+        this.count = count;
+        this.args = args;
     }
 
     public ResourceWrapper getResourceWrapper() {
@@ -80,15 +90,15 @@ public ResourceWrapper getResourceWrapper() {
 
     /**
      * Complete the current resource entry and restore the entry stack in context.
-     *
+     * Do not need to carry count or args parameter, initialization does
      * @throws ErrorEntryFreeException if entry in current context does not match current entry
      */
     public void exit() throws ErrorEntryFreeException {
-        exit(1, OBJECTS0);
+        exit(count, args);
     }
 
     public void exit(int count) throws ErrorEntryFreeException {
-        exit(count, OBJECTS0);
+        exit(count, args);
     }
 
     /**
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/SphO.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/SphO.java
index 592a3a0dcf..77db36330a 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/SphO.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/SphO.java
@@ -221,6 +221,6 @@ public static void exit(int count) {
     }
 
     public static void exit() {
-        exit(1, OBJECTS0);
+        ContextUtil.getContext().getCurEntry().exit();
     }
 }


Test patch:
diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/SphUTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/SphUTest.java
index e546f87c7f..50291446ad 100755
--- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/SphUTest.java
+++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/SphUTest.java
@@ -157,4 +157,14 @@ public void testMethodEntryAll() throws BlockException, NoSuchMethodException, S
 
         e.exit(2, arg0, arg1);
     }
+
+    @Test
+    public void testEntryExitAutomation() throws BlockException{
+        String[] args = {"foo", "baz"};
+        int batchCount = 3;
+        Entry e = SphU.entry("testEntryExitAutomation", EntryType.IN, 3, args);
+        e.exit();
+        // The number of success is automatically updated based on batchCount when exit
+        assertEquals(batchCount, e.getCurNode().totalSuccess());
+    }
 }