X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/9e60acc645d8ee8e223398830e1ccfed3ea18e80..e889ec14bbd18cf82acfabc681d0db967772692d:/sdk/go/keepclient/keepclient.go?ds=sidebyside diff --git a/sdk/go/keepclient/keepclient.go b/sdk/go/keepclient/keepclient.go index 853f4c61ef..f82e5c7c59 100644 --- a/sdk/go/keepclient/keepclient.go +++ b/sdk/go/keepclient/keepclient.go @@ -24,7 +24,7 @@ const BLOCKSIZE = 64 * 1024 * 1024 var BlockNotFound = errors.New("Block not found") var InsufficientReplicasError = errors.New("Could not write sufficient replicas") -var OversizeBlockError = errors.New("Exceeded maximum block size ("+strconv.Itoa(BLOCKSIZE)+")") +var OversizeBlockError = errors.New("Exceeded maximum block size (" + strconv.Itoa(BLOCKSIZE) + ")") var MissingArvadosApiHost = errors.New("Missing required environment variable ARVADOS_API_HOST") var MissingArvadosApiToken = errors.New("Missing required environment variable ARVADOS_API_TOKEN") var InvalidLocatorError = errors.New("Invalid locator") @@ -38,6 +38,7 @@ type KeepClient struct { Want_replicas int Using_proxy bool localRoots *map[string]string + writableLocalRoots *map[string]string gatewayRoots *map[string]string lock sync.RWMutex Client *http.Client @@ -126,7 +127,7 @@ func (kc *KeepClient) PutR(r io.Reader) (locator string, replicas int, err error func (kc *KeepClient) Get(locator string) (io.ReadCloser, int64, string, error) { var errs []string for _, host := range kc.getSortedRoots(locator) { - url := host+"/"+locator + url := host + "/" + locator req, err := http.NewRequest("GET", url, nil) if err != nil { continue @@ -148,8 +149,8 @@ func (kc *KeepClient) Get(locator string) (io.ReadCloser, int64, string, error) } return HashCheckingReader{ Reader: resp.Body, - Hash: md5.New(), - Check: locator[0:32], + Hash: md5.New(), + Check: locator[0:32], }, resp.ContentLength, url, nil } log.Printf("DEBUG: GET %s failed: %v", locator, errs) @@ -165,7 +166,7 @@ func (kc *KeepClient) Get(locator string) (io.ReadCloser, int64, string, error) // and the URI reporting the data size. func (kc *KeepClient) Ask(locator string) (int64, string, error) { for _, host := range kc.getSortedRoots(locator) { - url := host+"/"+locator + url := host + "/" + locator req, err := http.NewRequest("HEAD", url, nil) if err != nil { continue @@ -194,6 +195,14 @@ func (kc *KeepClient) GatewayRoots() map[string]string { return *kc.gatewayRoots } +// WritableLocalRoots() returns the map of writable local Keep services: +// uuid -> baseURI. +func (kc *KeepClient) WritableLocalRoots() map[string]string { + kc.lock.RLock() + defer kc.lock.RUnlock() + return *kc.writableLocalRoots +} + // SetServiceRoots updates the localRoots and gatewayRoots maps, // without risk of disrupting operations that are already in progress. // @@ -201,18 +210,26 @@ func (kc *KeepClient) GatewayRoots() map[string]string { // caller can reuse/modify them after SetServiceRoots returns, but // they should not be modified by any other goroutine while // SetServiceRoots is running. -func (kc *KeepClient) SetServiceRoots(newLocals, newGateways map[string]string) { +func (kc *KeepClient) SetServiceRoots(newLocals, newWritableLocals map[string]string, newGateways map[string]string) { locals := make(map[string]string) for uuid, root := range newLocals { locals[uuid] = root } + + writables := make(map[string]string) + for uuid, root := range newWritableLocals { + writables[uuid] = root + } + gateways := make(map[string]string) for uuid, root := range newGateways { gateways[uuid] = root } + kc.lock.Lock() defer kc.lock.Unlock() kc.localRoots = &locals + kc.writableLocalRoots = &writables kc.gatewayRoots = &gateways } @@ -246,8 +263,8 @@ func (kc *KeepClient) getSortedRoots(locator string) []string { type Locator struct { Hash string - Size int // -1 if data size is not known - Hints []string // Including the size hint, if any + Size int // -1 if data size is not known + Hints []string // Including the size hint, if any } func (loc *Locator) String() string {