// executeCmd runs Store.ExecuteCmd in a goroutine. A channel with // element type equal to the reply type is created and returned // immediately. The reply is sent to the channel once the cmd has been // executed by the store. The store is looked up from the store map // if specified by header.Replica; otherwise, the command is being // executed locally, and the replica is determined via lookup of // header.Key in the ranges slice. func (db *LocalDB) executeCmd(method string, header *storage.RequestHeader, args, reply interface{}) interface{} { chanVal := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(reply)), 1) replyVal := reflect.ValueOf(reply) go func() { // If the replica isn't specified in the header, look it up. var err error var store *storage.Store // If we aren't given a Replica, then a little bending over backwards here. We need to find the Store, but all // we have is the Key. So find its Range locally, and pull out its Replica which we use to find the Store. // This lets us use the same codepath below (store.ExecuteCmd) for both locally and remotely originated // commands. if header.Replica.NodeID == 0 { if repl := db.lookupReplica(header.Key); repl != nil { header.Replica = *repl } else { err = util.Errorf("unable to lookup range replica for key %q", string(header.Key)) } } if err == nil { store, err = db.GetStore(&header.Replica) } if err != nil { reflect.Indirect(replyVal).FieldByName("Error").Set(reflect.ValueOf(err)) } else { store.ExecuteCmd(method, header, args, reply) } chanVal.Send(replyVal) }() return chanVal.Interface() }
// executeCmd runs Store.ExecuteCmd in a goroutine. A channel with // element type equal to the reply type is created and returned // immediately. The reply is sent to the channel once the cmd has been // executed by the store. The store is looked up from the store map // if specified by header.Replica; otherwise, the command is being // executed locally, and the replica is determined via lookup of // header.Key in the ranges slice. func (db *LocalDB) executeCmd(method string, header *storage.RequestHeader, args, reply interface{}) interface{} { chanVal := reflect.MakeChan(reflect.ChanOf(reflect.BothDir, reflect.TypeOf(reply)), 1) replyVal := reflect.ValueOf(reply) go func() { // If the replica isn't specified in the header, look it up. var err error var store *storage.Store if header.Replica.NodeID == 0 { if repl := db.lookupReplica(header.Key); repl != nil { header.Replica = *repl } else { err = util.Errorf("unable to lookup range replica for key %q", string(header.Key)) } } if err == nil { store, err = db.GetStore(&header.Replica) } if err != nil { reflect.Indirect(replyVal).FieldByName("Error").Set(reflect.ValueOf(err)) } else { store.ExecuteCmd(method, header, args, reply) } chanVal.Send(replyVal) }() return chanVal.Interface() }