(ctx context.Context, qc *queryContext)
| 1564 | } |
| 1565 | |
| 1566 | func processQuery(ctx context.Context, qc *queryContext) (*api.Response, error) { |
| 1567 | resp := &api.Response{} |
| 1568 | if qc.req.Query == "" { |
| 1569 | // No query, so make the query cost 0. |
| 1570 | resp.Metrics = &api.Metrics{ |
| 1571 | NumUids: map[string]uint64{"_total": 0}, |
| 1572 | } |
| 1573 | return resp, nil |
| 1574 | } |
| 1575 | if ctx.Err() != nil { |
| 1576 | return resp, ctx.Err() |
| 1577 | } |
| 1578 | qr := query.Request{ |
| 1579 | Latency: qc.latency, |
| 1580 | DqlQuery: &qc.dqlRes, |
| 1581 | } |
| 1582 | |
| 1583 | // Here we try our best effort to not contact Zero for a timestamp. If we succeed, |
| 1584 | // then we use the max known transaction ts value (from ProcessDelta) for a read-only query. |
| 1585 | // If we haven't processed any updates yet then fall back to getting TS from Zero. |
| 1586 | switch { |
| 1587 | case qc.req.BestEffort: |
| 1588 | qc.span.AddEvent("", trace.WithAttributes(attribute.Bool("be", true))) |
| 1589 | case qc.req.ReadOnly: |
| 1590 | qc.span.AddEvent("", trace.WithAttributes(attribute.Bool("ro", true))) |
| 1591 | default: |
| 1592 | qc.span.AddEvent("", trace.WithAttributes(attribute.Bool("no", true))) |
| 1593 | } |
| 1594 | |
| 1595 | if qc.req.BestEffort { |
| 1596 | // Sanity: check that request is read-only too. |
| 1597 | if !qc.req.ReadOnly { |
| 1598 | return resp, errors.Errorf("A best effort query must be read-only.") |
| 1599 | } |
| 1600 | if qc.req.StartTs == 0 { |
| 1601 | qc.req.StartTs = posting.Oracle().MaxAssigned() |
| 1602 | } |
| 1603 | qr.Cache = worker.NoCache |
| 1604 | } |
| 1605 | |
| 1606 | if qc.req.StartTs == 0 { |
| 1607 | assignTimestampStart := time.Now() |
| 1608 | qc.req.StartTs = worker.State.GetTimestamp(qc.req.ReadOnly) |
| 1609 | qc.latency.AssignTimestamp = time.Since(assignTimestampStart) |
| 1610 | } |
| 1611 | |
| 1612 | qr.ReadTs = qc.req.StartTs |
| 1613 | resp.Txn = &api.TxnContext{StartTs: qc.req.StartTs} |
| 1614 | |
| 1615 | // Core processing happens here. |
| 1616 | er, err := qr.Process(ctx) |
| 1617 | |
| 1618 | if bool(glog.V(3)) || worker.LogDQLRequestEnabled() { |
| 1619 | glog.Infof("Finished a query that started at: %+v", |
| 1620 | qr.Latency.Start.Format(time.RFC3339)) |
| 1621 | } |
| 1622 | |
| 1623 | if err != nil { |
no test coverage detected