in src/main/scala/com/twitter/stitch/Pending.scala [203:245]
override def add[C, R](c: C, g: Group[C, R]): Stitch[R] = {
(g match {
case cfg: CallFutureGroup[_] =>
/**
* If it's a [[CallFutureGroup]] we want to check the cache to see if the parent [[Stitch.CallFuture]] instance is there instead
* this is because there will be different [[CallFutureGroup]] instances depending on the available [[com.twitter.util.Local]]s in scope
* at their creation, but if it's already been run we can just access the already computed value
*/
(
cfg.parentCallFutureInstance,
localCache.get((c, cfg.parentCallFutureInstance)).asInstanceOf[Stitch[R]])
case _ =>
(g, localCache.get((c, g)).asInstanceOf[Stitch[R]])
}) match {
case (localCacheKey, null) =>
// cache is empty, so go to the Runner with the actual group, not the `localCacheKey`
val stitch: Stitch[R] = super.add(c, g)
stitch match {
case s @ (SFuture(_, _) | Const(_)) =>
// simple single RPCs and constants can be cached
localCache.put((c, localCacheKey), s)
case s @ Transform(SFuture(_, _), _, a) if a.isInstanceOf[Apply[_, R]] =>
// this is the kind of Stitch a SeqRunner or a MapRunner returns from [[add]]
// it is ok to cache this because the Apply Arrow just unpacks the batch RPC response
localCache.put((c, localCacheKey), s)
case _ =>
// do not cache other types of Stitches
}
stitch
case (localCacheKey, s @ (SFuture(_, _) | Const(_) | Transform(_, _, _))) =>
// this call to [[simplify]] will return self, if the Future is not Done;
// or a Const if the Future is Done
val simplified = s.simplify(this)
localCache.put((c, localCacheKey), simplified)
simplified
case _ =>
// we are guaranteed not to get here
throw new UnsupportedOperationException("Unexpected")
}
}