@@ -350,7 +350,10 @@ class FetcherBase(kvStore: KVStore,
350
350
// 4. Finally converted to outputSchema
351
351
def fetchGroupBys (requests : scala.collection.Seq [Request ]): Future [scala.collection.Seq [Response ]] = {
352
352
// split a groupBy level request into its kvStore level requests
353
- val groupByRequestToKvRequest : Seq [(Request , Try [GroupByRequestMeta ])] = requests.iterator.map { request =>
353
+ // don't send to KV store if ANY of key's value is null
354
+ val validRequests =
355
+ requests.filter(r => r.keys == null || r.keys.values == null || ! r.keys.values.exists(_ == null ))
356
+ val groupByRequestToKvRequest : Seq [(Request , Try [GroupByRequestMeta ])] = validRequests.iterator.map { request =>
354
357
val groupByServingInfoTry = getGroupByServingInfo(request.name)
355
358
.recover {
356
359
case ex : Throwable =>
@@ -665,28 +668,8 @@ class FetcherBase(kvStore: KVStore,
665
668
}
666
669
Map (fetchException.getRequestName + " _exception" -> fetchException.getMessage)
667
670
}
668
- case Left (PrefixedRequest (prefix, groupByRequest)) => {
669
- responseMap
670
- .getOrElse(groupByRequest,
671
- Failure (new IllegalStateException (
672
- s " Couldn't find a groupBy response for $groupByRequest in response map " )))
673
- .map { valueMap =>
674
- if (valueMap != null ) {
675
- valueMap.map { case (aggName, aggValue) => prefix + " _" + aggName -> aggValue }
676
- } else {
677
- Map .empty[String , AnyRef ]
678
- }
679
- }
680
- // prefix feature names
681
- .recover { // capture exception as a key
682
- case ex : Throwable =>
683
- if (debug || Math .random() < 0.001 ) {
684
- logger.error(s " Failed to fetch $groupByRequest" , ex)
685
- }
686
- Map (prefix + " _exception" -> ex.traceString)
687
- }
688
- .get
689
- }
671
+ case Left (PrefixedRequest (prefix, groupByRequest)) =>
672
+ parseGroupByResponse(prefix, groupByRequest, responseMap)
690
673
}.toMap
691
674
}
692
675
joinValuesTry match {
@@ -706,6 +689,41 @@ class FetcherBase(kvStore: KVStore,
706
689
}
707
690
}
708
691
692
+ def parseGroupByResponse (prefix : String ,
693
+ groupByRequest : Request ,
694
+ responseMap : Map [Request , Try [Map [String , AnyRef ]]]) = {
695
+
696
+ // Group bys with ANY null keys won't be requested from the KV store and we don't expect a response.
697
+ val isRequiredRequest =
698
+ (groupByRequest.keys.nonEmpty && ! groupByRequest.keys.values.exists(_ == null )) || groupByRequest.keys.isEmpty
699
+
700
+ val response : Try [Map [String , AnyRef ]] = responseMap.get(groupByRequest) match {
701
+ case Some (value) => value
702
+ case None =>
703
+ if (isRequiredRequest)
704
+ Failure (new IllegalStateException (s " Couldn't find a groupBy response for $groupByRequest in response map " ))
705
+ else Success (null )
706
+ }
707
+
708
+ response
709
+ .map { valueMap =>
710
+ if (valueMap != null ) {
711
+ valueMap.map { case (aggName, aggValue) => prefix + " _" + aggName -> aggValue }
712
+ } else {
713
+ Map .empty[String , AnyRef ]
714
+ }
715
+ }
716
+ // prefix feature names
717
+ .recover { // capture exception as a key
718
+ case ex : Throwable =>
719
+ if (debug || Math .random() < 0.001 ) {
720
+ logger.error(s " Failed to fetch $groupByRequest" , ex)
721
+ }
722
+ Map (prefix + " _exception" -> ex.traceString)
723
+ }
724
+ .get
725
+ }
726
+
709
727
/**
710
728
* Fetch method to simulate a random access interface for Chronon
711
729
* by distributing requests to relevant GroupBys. This is a batch
0 commit comments