using System;
using Amazon.XRay.Recorder.Core.Internal.Entities;
using Amazon.XRay.Recorder.Core.Internal.Emitters;
using Amazon.XRay.Recorder.Core.Sampling;
namespace Amazon.XRay.Recorder.Core.Strategies
{
///
/// The default streaming strategy. It uses the total count of a segment's children subsegments as a threshold. If the threshold is breached, it uses subtree streaming to stream out.
///
public class DefaultStreamingStrategy : IStreamingStrategy
{
///
/// Default max subsegment size to stream for the strategy.
///
private const long DefaultMaxSubsegmentSize = 100;
///
/// Max subsegment size to stream fot the strategy.
///
public long MaxSubsegmentSize { get; private set; } = DefaultMaxSubsegmentSize;
///
/// Initializes a new instance of the class.
///
public DefaultStreamingStrategy() : this(DefaultMaxSubsegmentSize)
{
}
///
/// Initializes a new instance of the class.
///
///
public DefaultStreamingStrategy(long maxSubsegmentSize)
{
if(maxSubsegmentSize < 0)
{
throw new ArgumentException("maxSubsegmentSize cannot be a negative number.");
}
MaxSubsegmentSize = maxSubsegmentSize;
}
///
/// Checks whether subsegments of the current instance of should be streamed.
///
/// Instance of
/// True if the subsegments are streamable.
public bool ShouldStream(Entity entity)
{
return entity.Sampled == SampleDecision.Sampled && entity.RootSegment != null && entity.RootSegment.Size >= MaxSubsegmentSize;
}
///
/// Streams subsegments of instance of .
///
/// Instance of .
/// Instance of .
public void Stream(Entity entity, ISegmentEmitter emitter)
{
lock (entity.Subsegments)
{
foreach (var next in entity.Subsegments)
{
Stream(next, emitter);
}
entity.Subsegments.RemoveAll(x => x.HasStreamed);
}
if (entity.Sampled != SampleDecision.Sampled || entity is Segment || entity.IsInProgress || entity.Reference > 0 || entity.IsSubsegmentsAdded)
{
return;
}
Subsegment subsegment = entity as Subsegment;
subsegment.TraceId = entity.RootSegment.TraceId;
subsegment.Type = "subsegment";
subsegment.ParentId = subsegment.Parent.Id;
emitter.Send(subsegment);
subsegment.RootSegment.DecrementSize();
subsegment.HasStreamed = true;
}
}
}