in finagle-core/src/main/scala/com/twitter/finagle/Namer.scala [218:266]
private def bind(
lookup: Path => Activity[NameTree[Name]],
depth: Int,
weight: Option[Double]
)(
tree: NameTree[Name]
): Activity[NameTree[Name.Bound]] =
if (depth > namerMaxDepth())
Activity.exception(
new NamerExceededMaxDepthException(
s"Max recursion level: ${namerMaxDepth()} reached in Namer lookup"))
else
tree match {
case Leaf(Name.Path(path)) => lookup(path).flatMap(bind(lookup, depth + 1, weight))
case Leaf(bound @ Name.Bound(addr)) =>
// Add the weight of the parent to the addr's metadata
// Note: this assumes a single level of tree weights
val addrWithWeight = addr.map { addr =>
(addr, weight) match {
case (Addr.Bound(addrs, metadata), Some(weight)) =>
Addr.Bound(addrs, metadata + ((AddrWeightKey, weight)))
case _ => addr
}
}
Activity.value(Leaf(Name.Bound(addrWithWeight, bound.id, bound.path)))
case Fail => Activity.value(Fail)
case Neg => Activity.value(Neg)
case Empty => Activity.value(Empty)
case Union() => Activity.value(Neg)
case Union(Weighted(weight, tree)) => bind(lookup, depth, Some(weight))(tree)
case Union(trees @ _*) => bindUnion(lookup, depth, trees)
case Alt() => Activity.value(Neg)
case Alt(tree) => bind(lookup, depth, weight)(tree)
case Alt(trees @ _*) =>
def loop(trees: Seq[NameTree[Name]]): Activity[NameTree[Name.Bound]] =
trees match {
case Nil => Activity.value(Neg)
case Seq(head, tail @ _*) =>
bind(lookup, depth, weight)(head).flatMap {
case Fail => Activity.value(Fail)
case Neg => loop(tail)
case head => Activity.value(head)
}
}
loop(trees)
}