// RaftSnapshot handles incoming streaming snapshot requests. func (t *RaftTransport) RaftSnapshot(stream MultiRaft_RaftSnapshotServer) error { errCh := make(chan error, 1) if err := t.rpcContext.Stopper.RunAsyncTask(stream.Context(), func(ctx context.Context) { errCh <- func() error { req, err := stream.Recv() if err != nil { return err } if req.Header == nil { return stream.Send(&SnapshotResponse{ Status: SnapshotResponse_ERROR, Message: "client error: no header in first snapshot request message"}) } rmr := req.Header.RaftMessageRequest t.recvMu.Lock() handler, ok := t.recvMu.handlers[rmr.ToReplica.StoreID] t.recvMu.Unlock() if !ok { log.Warningf(ctx, "unable to accept Raft message from %+v: no handler registered for %+v", rmr.FromReplica, rmr.ToReplica) return roachpb.NewStoreNotFoundError(rmr.ToReplica.StoreID) } return handler.HandleSnapshot(req.Header, stream) }() }); err != nil { return err } select { case <-t.rpcContext.Stopper.ShouldStop(): return nil case err := <-errCh: return err } }
// GetStore looks up the store by store ID. Returns an error // if not found. func (ls *Stores) GetStore(storeID roachpb.StoreID) (*Store, error) { ls.mu.RLock() store, ok := ls.storeMap[storeID] ls.mu.RUnlock() if !ok { return nil, roachpb.NewStoreNotFoundError(storeID) } return store, nil }
// handleRaftRequest proxies a request to the listening server interface. func (t *RaftTransport) handleRaftRequest( ctx context.Context, req *RaftMessageRequest, respStream RaftMessageResponseStream, ) *roachpb.Error { t.recvMu.Lock() handler, ok := t.recvMu.handlers[req.ToReplica.StoreID] t.recvMu.Unlock() if !ok { log.Warningf(ctx, "unable to accept Raft message from %+v: no handler registered for %+v", req.FromReplica, req.ToReplica) return roachpb.NewError(roachpb.NewStoreNotFoundError(req.ToReplica.StoreID)) } return handler.HandleRaftRequest(ctx, req, respStream) }