func newRegion(ctx context.Context, ret chan newRegResult, clientType region.ClientType, host string, port uint16, queueSize int, queueTimeout time.Duration) { c, e := region.NewClient(host, port, clientType, queueSize, queueTimeout) select { case ret <- newRegResult{c, e}: // Hooray! case <-ctx.Done(): // We timed out, too bad, nobody expects this client anymore, ditch it. c.Close() } }
// Synchronously looks up the meta region in ZooKeeper. func (c *Client) locateMetaSync(errchan chan<- error) { host, port, err := zk.LocateMeta(c.zkquorum) if err != nil { log.Errorf("Error while locating meta: %s", err) errchan <- err return } log.WithFields(log.Fields{ "Host": host, "Port": port, }).Debug("Located META in ZooKeeper") c.metaClient, err = region.NewClient(host, port, c.rpcQueueSize, c.flushInterval) errchan <- err }
func TestMetaCache(t *testing.T) { client := newClient("~invalid.quorum~") // We shouldn't connect to ZK. reg := client.getRegionFromCache([]byte("test"), []byte("theKey")) if reg != nil { t.Errorf("Found region %#v even though the cache was empty?!", reg) } // Inject an entry in the cache. This entry covers the entire key range. wholeTable := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), nil, nil, ) regClient, _ := region.NewClient("", 0, region.RegionClient, 0, 0) client.regions.put(wholeTable) client.clients.put(regClient, wholeTable) reg = client.getRegionFromCache([]byte("test"), []byte("theKey")) if !reflect.DeepEqual(reg, wholeTable) { t.Errorf("Found region %#v but expected %#v", reg, wholeTable) } reg = client.getRegionFromCache([]byte("test"), []byte("")) // edge case. if !reflect.DeepEqual(reg, wholeTable) { t.Errorf("Found region %#v but expected %#v", reg, wholeTable) } // Clear our client. client = newClient("~invalid.quorum~") // Inject 3 entries in the cache. region1 := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("foo"), ) client.regions.put(region1) client.clients.put(regClient, region1) region2 := region.NewInfo( []byte("test"), []byte("test,foo,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("foo"), []byte("gohbase"), ) client.regions.put(region2) client.clients.put(regClient, region2) region3 := region.NewInfo( []byte("test"), []byte("test,gohbase,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("gohbase"), []byte(""), ) client.regions.put(region3) client.clients.put(regClient, region3) testcases := []struct { key string reg hrpc.RegionInfo }{ {key: "theKey", reg: region3}, {key: "", reg: region1}, {key: "bar", reg: region1}, {key: "fon\xFF", reg: region1}, {key: "foo", reg: region2}, {key: "foo\x00", reg: region2}, {key: "gohbase", reg: region3}, } for i, testcase := range testcases { reg = client.getRegionFromCache([]byte("test"), []byte(testcase.key)) if !reflect.DeepEqual(reg, testcase.reg) { t.Errorf("[#%d] Found region %#v but expected %#v", i, reg, testcase.reg) } } // Change the last region (maybe it got split). region3 = region.NewInfo( []byte("test"), []byte("test,gohbase,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), nil, []byte("zab"), ) client.regions.put(region3) client.clients.put(regClient, region3) reg = client.getRegionFromCache([]byte("test"), []byte("theKey")) if !reflect.DeepEqual(reg, region3) { t.Errorf("Found region %#v but expected %#v", reg, region3) } reg = client.getRegionFromCache([]byte("test"), []byte("zoo")) if reg != nil { t.Errorf("Shouldn't have found any region yet found %#v", reg) } }
} } else { return nil, nil, err } } return c.discoverRegion(ctx, resp.(*pb.GetResponse)) } type newRegResult struct { Client *region.Client Err error } var newRegion = func(ret chan newRegResult, host string, port uint16, queueSize int, queueTimeout time.Duration) { c, e := region.NewClient(host, port, queueSize, queueTimeout) ret <- newRegResult{c, e} } // Adds a new region to our regions cache. func (c *Client) discoverRegion(ctx context.Context, metaRow *pb.GetResponse) (*region.Client, *regioninfo.Info, error) { if metaRow.Result == nil { return nil, nil, errors.New("table not found") } var host string var port uint16 var reg *regioninfo.Info for _, cell := range metaRow.Result.Cell { switch string(cell.Qualifier) { case "regioninfo": var err error