feat(serving): allow some leeway time to return before xrefs deadline
@@ -34,6 +34,7 @@ import (
"path/filepath"
"regexp"
"strings"
+ "time"
"kythe.io/kythe/go/services/xrefs"
"kythe.io/kythe/go/storage/table"
@@ -65,6 +66,8 @@ var (
// TODO(schroederc): remove once relevant clients specify their required quality
defaultTotalsQuality = flag.String("experimental_default_totals_quality", "APPROXIMATE_TOTALS", "Default TotalsQuality when unspecified in CrossReferencesRequest")
+
+ responseLeewayTime = flag.Duration("xrefs_response_leeway_time", 50*time.Millisecond, "If possible, leave this much time at the end of a CrossReferencesRequest to return any results already read")
)
func init() {
@@ -628,6 +631,15 @@ func (t *Table) CrossReferences(ctx context.Context, req *xpb.CrossReferencesReq
return nil, err
}
+ var leewayTime time.Time
+ if d, ok := ctx.Deadline(); ok && *responseLeewayTime > 0 {
+ leewayTime = d.Add(-*responseLeewayTime)
+ if leewayTime.After(time.Now()) {
+ // Clear leeway time; try to use entire leftover timeout.
+ leewayTime = time.Time{}
+ }
+ }
+
filter, err := compileCorpusPathFilters(req.GetCorpusPathFilters(), t.ResolvePath)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid corpus_path_filters %s: %v", strings.ReplaceAll(req.GetCorpusPathFilters().String(), "\n", " "), err)
@@ -750,11 +762,17 @@ func (t *Table) CrossReferences(ctx context.Context, req *xpb.CrossReferencesReq
var indirectionPages []string
var foundCrossRefs bool
+readLoop:
for i := 0; i < len(tickets); i++ {
if totalsQuality == xpb.CrossReferencesRequest_APPROXIMATE_TOTALS && stats.done() {
break
}
+ if !leewayTime.IsZero() && time.Now().After(leewayTime) {
+ log.Println("WARNING: hit soft deadline; trying to return already read xrefs")
+ break
+ }
+
ticket := tickets[i]
cr, err := t.crossReferences(ctx, ticket)
if err == table.ErrNoSuchKey {
@@ -861,6 +879,11 @@ func (t *Table) CrossReferences(ctx context.Context, req *xpb.CrossReferencesReq
continue
}
+ if !leewayTime.IsZero() && time.Now().After(leewayTime) {
+ log.Println("WARNING: hit soft deadline; trying to return already read xrefs")
+ break readLoop
+ }
+
switch {
case xrefs.IsDefKind(req.DefinitionKind, idx.Kind, cr.Incomplete):
if !pageSet.Contains(idx) {
