// Get list of unique locators from the specified cluster func getUniqueLocators(kc *keepclient.KeepClient, prefix string) (map[string]bool, error) { uniqueLocators := map[string]bool{} // Get index and dedup for uuid := range kc.LocalRoots() { reader, err := kc.GetIndex(uuid, prefix) if err != nil { return uniqueLocators, err } scanner := bufio.NewScanner(reader) for scanner.Scan() { uniqueLocators[strings.Split(scanner.Text(), " ")[0]] = true } } return uniqueLocators, nil }
// ComputePullServers creates a map from block locator to PullServers // with one entry for each under-replicated block. // // This method ignores zero-replica blocks since there are no servers // to pull them from, so callers should feel free to omit them, but // this function will ignore them if they are provided. func ComputePullServers(kc *keepclient.KeepClient, keepServerInfo *keep.ReadServers, blockToDesiredReplication map[blockdigest.DigestWithSize]int, underReplicated BlockSet) (m map[Locator]PullServers) { m = map[Locator]PullServers{} // We use CanonicalString to avoid filling memory with dupicate // copies of the same string. var cs CanonicalString // Servers that are writeable writableServers := map[string]struct{}{} for _, url := range kc.WritableLocalRoots() { writableServers[cs.Get(url)] = struct{}{} } for block := range underReplicated { serversStoringBlock := keepServerInfo.BlockToServers[block] numCopies := len(serversStoringBlock) numCopiesMissing := blockToDesiredReplication[block] - numCopies if numCopiesMissing > 0 { // We expect this to always be true, since the block was listed // in underReplicated. if numCopies > 0 { // Not much we can do with blocks with no copies. // A server's host-port string appears as a key in this map // iff it contains the block. serverHasBlock := map[string]struct{}{} for _, info := range serversStoringBlock { sa := keepServerInfo.KeepServerIndexToAddress[info.ServerIndex] serverHasBlock[cs.Get(sa.URL())] = struct{}{} } roots := keepclient.NewRootSorter(kc.LocalRoots(), block.String()).GetSortedRoots() l := Locator(block) m[l] = CreatePullServers(cs, serverHasBlock, writableServers, roots, numCopiesMissing) } } } return m }
// Refresh the keep service list every five minutes. func RefreshServicesList(kc *keepclient.KeepClient) { var previousRoots = []map[string]string{} var delay time.Duration = 0 for { time.Sleep(delay * time.Second) delay = 300 if err := kc.DiscoverKeepServers(); err != nil { log.Println("Error retrieving services list:", err) delay = 3 continue } newRoots := []map[string]string{kc.LocalRoots(), kc.GatewayRoots()} if !reflect.DeepEqual(previousRoots, newRoots) { log.Printf("Updated services list: locals %v gateways %v", newRoots[0], newRoots[1]) } if len(newRoots[0]) == 0 { log.Print("WARNING: No local services. Retrying in 3 seconds.") delay = 3 } previousRoots = newRoots } }
func runProxy(c *C, args []string, port int, bogusClientToken bool) keepclient.KeepClient { if bogusClientToken { os.Setenv("ARVADOS_API_TOKEN", "bogus-token") } arv, err := arvadosclient.MakeArvadosClient() c.Assert(err, Equals, nil) kc := keepclient.KeepClient{ Arvados: &arv, Want_replicas: 2, Using_proxy: true, Client: &http.Client{}, } locals := map[string]string{ "proxy": fmt.Sprintf("http://localhost:%v", port), } writableLocals := map[string]string{ "proxy": fmt.Sprintf("http://localhost:%v", port), } kc.SetServiceRoots(locals, writableLocals, nil) c.Check(kc.Using_proxy, Equals, true) c.Check(len(kc.LocalRoots()), Equals, 1) for _, root := range kc.LocalRoots() { c.Check(root, Equals, fmt.Sprintf("http://localhost:%v", port)) } log.Print("keepclient created") if bogusClientToken { arvadostest.ResetEnv() } { os.Args = append(args, fmt.Sprintf("-listen=:%v", port)) listener = nil go main() } return kc }