Scala DV Judge PoC — evaluates DVs and maps all 16 proto fields

Mark Eibes
2026-04-21T14:49:24Z

judge.scala

| //> using scala 3.5
| //> using jar "dv_3_latest.jar"
| //> using dep "org.typelevel::cats-effect:3.7.0"
| //> using dep "com.lihaoyi::ujson:4.0.0"
| //> using dep "com.thesamet.scalapb::scalapb-runtime:1.0.0-alpha.3"
|
| import cats.effect.{IO, IOApp}
| import cats.syntax.all.*
| import com.doordash.dv.DVClient
| import com.doordash.dv.entity.*
| import com.doordash.dv.listener.NoOpListener
|
| /** Simulates what the Scala DV Judge would do:
| * 1. Load DV configs from a directory
| * 2. Accept evaluation requests (name + properties)
| * 3. Evaluate the DV
| * 4. Map the result to proto-like output (JSON here)
| */
| object JudgePoc extends IOApp.Simple:
|
| def evaluationToProto(eval: Evaluation): ujson.Obj =
| ujson.Obj(
| "name" -> eval.name.value,
| "segment" -> eval.segment.map(_.value).getOrElse(""),
| "distribution" -> eval.distribution.map(_.value).getOrElse(""),
| "variant_name" -> eval.variant.name.value,
| "variant_value" -> eval.variant.value.toString,
| "in_rollout" -> eval.inRollout,
| "revision" -> eval.revision,
| "type" -> eval.dvType.toString,
| "rollout_fraction" -> eval.rolloutFraction,
| "variant_fraction" -> eval.variantFraction,
| "segment_rollout_fraction" -> eval.segmentRolloutFraction,
| "randomization_key" -> eval.randomizationKey,
| "randomization_value" -> eval.randomizationValue,
| "group_id" -> eval.groupId,
| "random_pair" -> eval.randomPair,
| "random_mirror" -> eval.randomMirror,
| )
|
| def run: IO[Unit] =
| for
| _ <- IO.println("=== Scala DV Judge PoC ===\n")
| dv <- DVClient.fromDirectory[IO](ConfigDir("configs"), NoOpListener[IO], validate = true)
|
| // Simulate judge request: PedregalDVEvaluation(name="dv_1", properties={country: "US"})
| _ <- IO.println("--- Request: PedregalDVEvaluation ---")
| _ <- IO.println(" input: name=dv_1, properties={country=US, user=user-12345}")
|
| props = Properties.empty
| .setString(PropertyKey("country"), "US")
| .setRandomizationKey(RandomizationKey("user-12345"))
|
| // Evaluate
| result <- dv.evaluateSet(DVName("dv_1"), props)
| primary = result.evaluationSets.get(DVName("dv_1"))
|
| // Debug: show what keys exist
| _ <- IO.println(s"\n evaluationSets keys: ${result.evaluationSets.keys.map(_.value).mkString(", ")}")
| _ <- result.evaluationSets.values.toList.traverse_ { evalSet =>
| IO.println(s" evaluations keys: ${evalSet.evaluations.keys.map(_.value).mkString(", ")}")
| }
|
| // Map primary evaluation to proto response
| _ <- IO.println("\n--- Response: PedregalDVEvaluationResponse ---")
| eval1 <- dv.evaluate(DVName("dv_1"), props)
| proto1 = evaluationToProto(eval1)
| _ <- IO.println(ujson.write(proto1, indent = 2))
|
| // Show dependent evaluations
| _ <- IO.println("\n--- Dependent Evaluations ---")
| _ <- result.evaluationSets.toList.traverse_ { case (name, set) =>
| set.evaluations.toList.traverse_ { case (dvName, eval) =>
| IO.println(s" ${name.value} -> ${dvName.value}: variant=${eval.variant.name.value}")
| }
| }
|
| // Simulate second request
| _ <- IO.println("\n--- Request 2: PedregalDVEvaluation(dv_2) ---")
| eval2 <- dv.evaluate(DVName("dv_2"), props)
| proto2 = evaluationToProto(eval2)
| _ <- IO.println(ujson.write(proto2, indent = 2))
|
| // Simulate missing DV (judge should return error)
| _ <- IO.println("\n--- Request 3: PedregalDVEvaluation(nonexistent) ---")
| missing <- dv.evaluate(DVName("nonexistent"), props).attempt
| _ <- missing match
| case Left(err) => IO.println(s" Error (expected): ${err.getMessage}")
| case Right(eval) => IO.println(s" Unexpected: ${eval.variant.name.value}")
|
| _ <- IO.println("\n=== Judge PoC Complete ===")
| yield ()