예제 #1
0
func (c *client) establishRegion(originalReg hrpc.RegionInfo, host string, port uint16) {
	var err error
	reg := originalReg
	backoff := backoffStart

	for {
		ctx, _ := context.WithTimeout(context.Background(), regionLookupTimeout)
		if port != 0 && err == nil {
			// If this isn't the admin or meta region, check if a client
			// for this host/port already exists
			if c.clientType != adminClient && reg != c.metaRegionInfo {
				client := c.clients.checkForClient(host, port)
				if client != nil {
					// There's already a client, add it to the
					// region and mark it as available.
					reg.SetClient(client)
					c.clients.put(client, reg)
					originalReg.MarkAvailable()
					return
				}
			}
			// Make this channel buffered so that if we time out we don't
			// block the newRegion goroutine forever.
			ch := make(chan newRegResult, 1)
			var clientType region.ClientType
			if c.clientType == standardClient {
				clientType = region.RegionClient
			} else {
				clientType = region.MasterClient
			}
			go newRegionClient(ctx, ch, clientType, host, port, c.rpcQueueSize, c.flushInterval)

			select {
			case res := <-ch:
				if res.Err == nil {
					reg.SetClient(res.Client)
					if c.clientType != adminClient && reg != c.metaRegionInfo {
						// put will set region client so that as soon as we add
						// it to the key->region mapping, concurrent readers are
						// able to find the client
						c.clients.put(res.Client, reg)
						if reg != originalReg {
							removed := c.regions.put(reg)
							for _, r := range removed {
								c.clients.del(r)
							}
						}
					}
					originalReg.MarkAvailable()
					return
				} else {
					err = res.Err
				}
			case <-ctx.Done():
				err = ErrDeadline
			}
		}
		if err != nil {
			if err == TableNotFound {
				c.regions.del(originalReg.Name())
				originalReg.MarkAvailable()
				return
			}
			// This will be hit if either there was an error locating the
			// region, or the region was located but there was an error
			// connecting to it.
			backoff, err = sleepAndIncreaseBackoff(ctx, backoff)
			if err != nil {
				continue
			}
		}
		if c.clientType == adminClient {
			host, port, err = c.zkLookup(ctx, c.master)
		} else if reg == c.metaRegionInfo {
			host, port, err = c.zkLookup(ctx, c.meta)
		} else {
			reg, host, port, err = c.locateRegion(ctx, originalReg.Table(),
				originalReg.StartKey())
		}
	}
}
예제 #2
0
func isRegionOverlap(regA, regB hrpc.RegionInfo) bool {
	return bytes.Equal(regA.Table(), regB.Table()) &&
		bytes.Compare(regA.StartKey(), regB.StopKey()) < 0 &&
		bytes.Compare(regA.StopKey(), regB.StartKey()) > 0
}