You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by GitBox <gi...@apache.org> on 2020/01/17 14:54:40 UTC

[GitHub] [skywalking] kezhenxu94 commented on a change in pull request #4220: sniffer processing profile task and report status and snapshot

kezhenxu94 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_r367943992
 
 

 ##########
 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:
   This line is really confusing, what does it do?

----------------------------------------------------------------
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:
users@infra.apache.org


With regards,
Apache Git Services