package org.skywalking.apm.agent.core.sampling;

import org.skywalking.apm.agent.core.boot.BootService;
import org.skywalking.apm.agent.core.conf.Config;
import org.skywalking.apm.agent.core.context.ContextCarrier;
import org.skywalking.apm.logging.ILog;
import org.skywalking.apm.logging.LogManager;
import org.skywalking.apm.trace.TraceSegment;

/**
 * The <code>SamplingService</code> take charge of how to sample the {@link TraceSegment}. Every {@link TraceSegment}s
 * have been traced, but, considering CPU cost of serialization/deserialization, and network bandwidth, the agent do NOT
 * send all of them to collector, if SAMPLING is on.
 * <p>
 * By default, SAMPLING is off, and {@link Config.Agent#SAMPLING_CYCLE} == 1.
 *
 * @author wusheng
 */
public class SamplingService implements BootService {
    private static final ILog logger = LogManager.getLogger(SamplingService.class);

    private volatile boolean on = false;
    private volatile int rollingSeed = 1;

    @Override
    public void bootUp() throws Throwable {
        if (Config.Agent.SAMPLING_CYCLE == 1) {
            this.on = false;
            return;
        }
        if (Config.Agent.SAMPLING_CYCLE < 1) {
            throw new IllegalSamplingRateException("sampling cycle must greater than 0.");
        }
        this.on = true;

        logger.debug("The trace sampling is on, and the sampling cycle is: {}", Config.Agent.SAMPLING_CYCLE);
    }

    public void trySampling(TraceSegment segment) {
        if (on) {
            if (rollingSeed % Config.Agent.SAMPLING_CYCLE != 0) {
                segment.setSampled(false);
                this.rollingSeed = 1;
            }
            rollingSeed++;
        }
    }

    /**
     * Set the {@link TraceSegment} to sampled, when {@link ContextCarrier} contains "isSampled" flag.
     * <p>
     * A -> B, if TraceSegment is sampled in A, then the related TraceSegment in B must be sampled, no matter you
     * sampling rate. And reset the {@link #rollingSeed}, in case of too many {@link TraceSegment}s, which started in
     * this JVM, are sampled.
     *
     * @param segment the current TraceSegment.
     * @param carrier
     */
    public void setSampleWhenExtract(TraceSegment segment, ContextCarrier carrier) {
        if (on) {
            if (!segment.isSampled() && carrier.isSampled()) {
                segment.setSampled(true);
                this.rollingSeed = 1;
            }
        }
    }

}

@@ -1614,37 +1614,32 @@
                 
-this.
 rollingSeed = 1;
@@ -1625,36 +1625,34 @@
      rollingSeed
- = 1
+++
 ;%0A            %7D%0A
@@ -1642,32 +1642,37 @@
 +;%0A            %7D
+else%7B
 %0A            rol
@@ -1660,32 +1660,41 @@
 se%7B%0A            
+    this.
 rollingSeed++;%0A 
@@ -1680,35 +1680,51 @@
 this.rollingSeed
-++;
+ = 1;%0A            %7D
 %0A        %7D%0A    %7D

Fix sampling bug.