wu-sheng commented on a change in pull request #4220: sniffer processing 
profile task and report status and snapshot
URL: https://github.com/apache/skywalking/pull/4220#discussion_r368015051
 
 

 ##########
 File path: 
apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/profile/ProfileTaskExecutionContext.java
 ##########
 @@ -30,22 +37,139 @@
     // task data
     private final ProfileTask task;
 
-    // task real start time
-    private final long startTime;
+    // record current profiling count, use this to check has available profile 
slot
+    private final AtomicInteger currentProfilingCount = new AtomicInteger(0);
+
+    // profiling segment slot
+    private volatile ThreadProfiler[] profilingSegmentSlots = new 
ThreadProfiler[Config.Profile.MAX_PARALLEL];
+
+    // current profiling execution future
+    private volatile Future profilingFuture;
+
+    // total started profiling tracing context count
+    private final AtomicInteger totalStartedProfilingCount = new 
AtomicInteger(0);
 
-    public ProfileTaskExecutionContext(ProfileTask task, long startTime) {
+    public ProfileTaskExecutionContext(ProfileTask task) {
         this.task = task;
-        this.startTime = startTime;
+    }
+
+    /**
+     * start profiling this task
+     * @param executorService
+     */
+    public void startProfiling(ExecutorService executorService) {
+        profilingFuture = executorService.submit(new ProfileThread(this));
+    }
+
+    /**
+     * stop profiling
+     */
+    public void stopProfiling() {
+        if (profilingFuture != null) {
+            profilingFuture.cancel(true);
+        }
+    }
+
+    /**
+     * check have available slot to profile and add it
+     * @param tracingContext
+     * @param firstSpanOPName
+     * @return
+     */
+    public boolean attemptProfiling(TracingContext tracingContext, ID 
traceSegmentId, String firstSpanOPName) {
+        // check has available slot
+        final int usingSlotCount = currentProfilingCount.get();
+        if (usingSlotCount >= Config.Profile.MAX_PARALLEL) {
+            return false;
+        }
+
+        // check first operation name matches
+        if (!Objects.equals(task.getFistSpanOPName(), firstSpanOPName)) {
+            return false;
+        }
+
+        return tryToAttemptProfiling(tracingContext, traceSegmentId, 
firstSpanOPName, usingSlotCount);
+    }
+
+
+    /**
+     * profiling recheck
+     * @param tracingContext
+     * @param traceSegmentId
+     * @param firstSpanOPName
+     * @return
+     */
+    public boolean profilingRecheck(TracingContext tracingContext, ID 
traceSegmentId, String firstSpanOPName) {
+        boolean alreadyProfiling = tracingContext.isProfiling();
+
+        // not profiling and not available slot don't check anymore
+        int usingSlotCount = currentProfilingCount.get();
+        if (!alreadyProfiling && usingSlotCount >= 
Config.Profile.MAX_PARALLEL) {
+            return false;
+        }
+
+        // check first operation name matches
+        if (!Objects.equals(task.getFistSpanOPName(), firstSpanOPName)) {
+            if (alreadyProfiling) {
+                if (stopTracingProfile(tracingContext)) {
+                    // reduce total started profiling count when status is 
profiling
+                    totalStartedProfilingCount.addAndGet(-1);
+                }
+            }
+            return false;
+        } else if (alreadyProfiling) {
+            return true;
+        }
+
+        // not profiling, try to occupy slot
+        return tryToAttemptProfiling(tracingContext, traceSegmentId, 
firstSpanOPName, usingSlotCount);
+    }
+
+    /**
+     * find tracing context and clear on slot
+     *
+     * @param tracingContext
+     *
+     * @return current profiler is already start profiling
+     */
+    public boolean stopTracingProfile(TracingContext tracingContext) {
+        // find current tracingContext and clear it
+        boolean isProfilingStarted = false;
+        for (int slot = 0; slot < profilingSegmentSlots.length; slot++) {
+            ThreadProfiler currentProfiler = profilingSegmentSlots[slot];
+            if (currentProfiler != null && 
currentProfiler.matches(tracingContext)) {
+                profilingSegmentSlots[slot] = null;
+
+                // setting stop running
+                isProfilingStarted = currentProfiler.stopProfiling();
+                currentProfilingCount.addAndGet(-1);
+
+                profilingSegmentSlots = profilingSegmentSlots;
 
 Review comment:
   I remember that did this in different way. Can't remember the 
detail.Personally, I just use the easy way. 
    @mrproliu you could add doc, but don't use the link to that blog.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to