mirror of
https://github.com/talent-plan/tinykv.git
synced 2025-02-14 13:50:07 +08:00
Signed-off-by: Connor <zbk602423539@gmail.com> Co-authored-by: Nick Cameron <nrc@ncameron.org> Co-authored-by: linning <linningde25@gmail.com> Co-authored-by: YangKeao <keao.yang@yahoo.com> Co-authored-by: andylokandy <andylokandy@hotmail.com> Co-authored-by: Iosmanthus Teng <myosmanthustree@gmail.com>
68 lines
1.6 KiB
Go
68 lines
1.6 KiB
Go
package raft_storage
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/pingcap-incubator/tinykv/kv/util/worker"
|
|
|
|
"github.com/pingcap-incubator/tinykv/kv/raftstore/scheduler_client"
|
|
"github.com/pingcap-incubator/tinykv/proto/pkg/metapb"
|
|
"github.com/pingcap/errors"
|
|
)
|
|
|
|
// Handle will resolve t's storeID into the address of the TinyKV node which should handle t. t's callback is then
|
|
// called with that address.
|
|
func (r *resolverRunner) Handle(t worker.Task) {
|
|
data := t.(*resolveAddrTask)
|
|
data.callback(r.getAddr(data.storeID))
|
|
}
|
|
|
|
const storeAddressRefreshSeconds = 60
|
|
|
|
type storeAddr struct {
|
|
addr string
|
|
lastUpdate time.Time
|
|
}
|
|
|
|
type resolverRunner struct {
|
|
schedulerClient scheduler_client.Client
|
|
storeAddrs map[uint64]storeAddr
|
|
}
|
|
|
|
type resolveAddrTask struct {
|
|
storeID uint64
|
|
callback func(addr string, err error)
|
|
}
|
|
|
|
func newResolverRunner(schedulerClient scheduler_client.Client) *resolverRunner {
|
|
return &resolverRunner{
|
|
schedulerClient: schedulerClient,
|
|
storeAddrs: make(map[uint64]storeAddr),
|
|
}
|
|
}
|
|
|
|
func (r *resolverRunner) getAddr(id uint64) (string, error) {
|
|
if sa, ok := r.storeAddrs[id]; ok {
|
|
if time.Since(sa.lastUpdate).Seconds() < storeAddressRefreshSeconds {
|
|
return sa.addr, nil
|
|
}
|
|
}
|
|
store, err := r.schedulerClient.GetStore(context.TODO(), id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if store.GetState() == metapb.StoreState_Tombstone {
|
|
return "", errors.Errorf("store %d has been removed", id)
|
|
}
|
|
addr := store.GetAddress()
|
|
if addr == "" {
|
|
return "", errors.Errorf("invalid empty address for store %d", id)
|
|
}
|
|
r.storeAddrs[id] = storeAddr{
|
|
addr: addr,
|
|
lastUpdate: time.Now(),
|
|
}
|
|
return addr, nil
|
|
}
|