/// <summary>
        /// Replace <see cref="Sampler"/> with a new instance when parameters are updated.
        /// </summary>
        /// <param name="response">Response which contains either a <see cref="ProbabilisticSampler"/>
        /// or <see cref="RateLimitingSampler"/>.</param>
        private void UpdateRateLimitingOrProbabilisticSampler(SamplingStrategyResponse response)
        {
            ISampler sampler;

            if (response.ProbabilisticSampling != null)
            {
                ProbabilisticSamplingStrategy strategy = response.ProbabilisticSampling;
                sampler = new ProbabilisticSampler(strategy.SamplingRate);
            }
            else if (response.RateLimitingSampling != null)
            {
                RateLimitingSamplingStrategy strategy = response.RateLimitingSampling;
                sampler = new RateLimitingSampler(strategy.MaxTracesPerSecond);
            }
            else
            {
                _metrics.SamplerParsingFailure.Inc(1);
                _logger.LogError("No strategy present in response. Not updating sampler.");
                return;
            }

            lock (_lock)
            {
                if (!Sampler.Equals(sampler))
                {
                    Sampler.Close();
                    Sampler = sampler;
                    _metrics.SamplerUpdated.Inc(1);
                }
            }
        }
        /// <summary>
        /// Updates the probabilistic and lowerBound samplers.
        /// </summary>
        /// <param name="samplingRate">The sampling rate for probabilistic sampling.</param>
        /// <param name="lowerBound">The lower bound limit for lower bound sampling.</param>
        /// <returns><c>true</c>, if any samplers were updated.</returns>
        public virtual bool Update(double samplingRate, double lowerBound)
        {
            lock (_lock)
            {
                var isUpdated = false;
                if (samplingRate != _probabilisticSampler.SamplingRate)
                {
                    _probabilisticSampler.Close();
                    _probabilisticSampler = new ProbabilisticSampler(samplingRate);

                    var newTags = new Dictionary <string, object>();
                    foreach (var oldTag in _tags)
                    {
                        newTags[oldTag.Key] = oldTag.Value;
                    }
                    newTags[Constants.SamplerParamTagKey] = samplingRate;

                    _tags     = newTags;
                    isUpdated = true;
                }
                if (lowerBound != _lowerBoundSampler.MaxTracesPerSecond)
                {
                    _lowerBoundSampler.Close();
                    _lowerBoundSampler = new RateLimitingSampler(lowerBound);
                    isUpdated          = true;
                }
                return(isUpdated);
            }
        }
        public GuaranteedThroughputSampler(double samplingRate, double lowerBound)
        {
            _tags = new Dictionary <string, object> {
                { Constants.SamplerTypeTagKey, Type },
                { Constants.SamplerParamTagKey, samplingRate }
            };

            _probabilisticSampler = new ProbabilisticSampler(samplingRate);
            _lowerBoundSampler    = new RateLimitingSampler(lowerBound);
        }
 internal PerOperationSampler(
     int maxOperations,
     Dictionary <string, GuaranteedThroughputSampler> samplers,
     ProbabilisticSampler probabilisticSampler,
     double lowerBound,
     ILoggerFactory loggerFactory)
 {
     MaxOperations          = maxOperations;
     OperationNameToSampler = samplers ?? new Dictionary <string, GuaranteedThroughputSampler>();
     DefaultSampler         = probabilisticSampler ?? throw new ArgumentNullException(nameof(probabilisticSampler));
     LowerBound             = lowerBound;
     _logger = loggerFactory?.CreateLogger <PerOperationSampler>() ?? throw new ArgumentNullException(nameof(loggerFactory));
 }
 public RemoteControlledSampler Build()
 {
     if (LoggerFactory == null)
     {
         LoggerFactory = NullLoggerFactory.Instance;
     }
     if (InitialSampler == null)
     {
         InitialSampler = new ProbabilisticSampler();
     }
     if (Metrics == null)
     {
         Metrics = new MetricsImpl(NoopMetricsFactory.Instance);
     }
     return(new RemoteControlledSampler(this));
 }
        /// <summary>
        /// Updates the <see cref="GuaranteedThroughputSampler"/> for each operation.
        /// </summary>
        /// <param name="strategies">The parameters for operation sampling.</param>
        /// <returns><c>true</c>, if any samplers were updated.</returns>
        public bool Update(OperationSamplingParameters strategies)
        {
            lock (_lock)
            {
                var isUpdated = false;

                LowerBound = strategies.DefaultLowerBoundTracesPerSecond;
                ProbabilisticSampler defaultSampler = new ProbabilisticSampler(strategies.DefaultSamplingProbability);

                if (!defaultSampler.Equals(DefaultSampler))
                {
                    DefaultSampler.Close();
                    DefaultSampler = defaultSampler;
                    isUpdated      = true;
                }

                foreach (var strategy in strategies.PerOperationStrategies)
                {
                    var operation    = strategy.Operation;
                    var samplingRate = strategy.ProbabilisticSampling.SamplingRate;
                    if (OperationNameToSampler.TryGetValue(operation, out var sampler))
                    {
                        isUpdated = sampler.Update(samplingRate, LowerBound) || isUpdated;
                    }
                    else
                    {
                        if (OperationNameToSampler.Count < MaxOperations)
                        {
                            sampler = new GuaranteedThroughputSampler(samplingRate, LowerBound);
                            OperationNameToSampler[operation] = sampler;
                            isUpdated = true;
                        }
                        else
                        {
                            _logger.LogInformation("Exceeded the maximum number of operations {maxOperations} for per operations sampling", MaxOperations);
                        }
                    }
                }

                return(isUpdated);
            }
        }