All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.janstenpickle.trace4cats.rate.sampling.RateTailSpanSampler.scala Maven / Gradle / Ivy

The newest version!
package io.janstenpickle.trace4cats.rate.sampling

import cats.effect.kernel.{Resource, Temporal}
import cats.syntax.functor._
import cats.{Applicative, Foldable, Monad, MonoidK}
import io.janstenpickle.trace4cats.model.{CompletedSpan, SampleDecision, TraceId}
import io.janstenpickle.trace4cats.rate.TokenBucket
import io.janstenpickle.trace4cats.sampling.tail.{SampleDecisionStore, TailSpanSampler}
import cats.syntax.foldable._

import scala.concurrent.duration.FiniteDuration

object RateTailSpanSampler {
  def apply[F[_]: Monad: TokenBucket, G[_]: Applicative: Foldable: MonoidK](
    store: SampleDecisionStore[F]
  ): TailSpanSampler[F, G] =
    TailSpanSampler.storedBatchComputation[F, G](
      store,
      _ =>
        TokenBucket[F].request1.map {
          case false => SampleDecision.Drop
          case true => SampleDecision.Include
        },
      (batch, traceIds) => {
        TokenBucket[F].request(traceIds.size).map { tokens =>
          val sampled = traceIds.take(tokens)

          batch.foldLeft((MonoidK[G].empty[CompletedSpan], Map.empty[TraceId, SampleDecision])) {
            case ((spans, decisions), span) =>
              val traceId = span.context.traceId

              decisions.get(traceId) match {
                case Some(SampleDecision.Drop) => (spans, decisions)
                case Some(SampleDecision.Include) => (TailSpanSampler.combine(span, spans), decisions)
                case None =>
                  if (sampled.contains(traceId))
                    (TailSpanSampler.combine(span, spans), decisions.updated(traceId, SampleDecision.Include))
                  else (spans, decisions.updated(traceId, SampleDecision.Drop))
              }
          }

        }
      }
    )

  def create[F[_]: Temporal, G[_]: Applicative: Foldable: MonoidK](
    store: SampleDecisionStore[F],
    bucketSize: Int,
    tokenRate: FiniteDuration
  ): Resource[F, TailSpanSampler[F, G]] =
    TokenBucket.create[F](bucketSize, tokenRate).map(implicit tb => apply[F, G](store))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy