BelongsToReadOnly acts like BelongsTo except it does not ask zero to serve the tablet for key if no group is currently serving it. The ts passed should be the start ts of the query, so this method can compare that against a tablet move timestamp. If the tablet was moved to this group after the start
(key string, ts uint64)
| 409 | // tablet move timestamp. If the tablet was moved to this group after the start ts of the query, we |
| 410 | // should reject that query. |
| 411 | func (g *groupi) BelongsToReadOnly(key string, ts uint64) (uint32, error) { |
| 412 | g.RLock() |
| 413 | tablet := g.tablets[key] |
| 414 | g.RUnlock() |
| 415 | if tablet != nil { |
| 416 | if ts > 0 && ts < tablet.MoveTs { |
| 417 | return 0, errors.Errorf("StartTs: %d is from before MoveTs: %d for pred: %q", |
| 418 | ts, tablet.MoveTs, key) |
| 419 | } |
| 420 | return tablet.GetGroupId(), nil |
| 421 | } |
| 422 | |
| 423 | // We don't know about this tablet. Talk to dgraphzero to find out who is |
| 424 | // serving this tablet. |
| 425 | pl := g.connToZeroLeader() |
| 426 | zc := pb.NewZeroClient(pl.Get()) |
| 427 | |
| 428 | tablet = &pb.Tablet{ |
| 429 | Predicate: key, |
| 430 | ReadOnly: true, |
| 431 | } |
| 432 | out, err := zc.ShouldServe(g.Ctx(), tablet) |
| 433 | if err != nil { |
| 434 | glog.Errorf("Error while ShouldServe grpc call %v", err) |
| 435 | return 0, err |
| 436 | } |
| 437 | if out.GetGroupId() == 0 { |
| 438 | return 0, nil |
| 439 | } |
| 440 | |
| 441 | g.Lock() |
| 442 | defer g.Unlock() |
| 443 | g.tablets[key] = out |
| 444 | if out != nil && ts > 0 && ts < out.MoveTs { |
| 445 | return 0, errors.Errorf("StartTs: %d is from before MoveTs: %d for pred: %q", |
| 446 | ts, out.MoveTs, key) |
| 447 | } |
| 448 | return out.GetGroupId(), nil |
| 449 | } |
| 450 | |
| 451 | func (g *groupi) ServesTablet(key string) (bool, error) { |
| 452 | if tablet, err := g.Tablet(key); err != nil { |
no test coverage detected