mirror of
https://github.com/talent-plan/tinykv.git
synced 2025-02-15 06:10:08 +08:00
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
|
||
|
}
|