func (rs *ReplValueStore) SetRing(r ring.Ring) { if r == nil { return } rs.ringLock.Lock() if rs.ringCachePath != "" { dir, name := path.Split(rs.ringCachePath) _ = os.MkdirAll(dir, 0755) fp, err := ioutil.TempFile(dir, name) if err != nil { rs.logDebug("replValueStore: error caching ring %q: %s", rs.ringCachePath, err) } else if err := r.Persist(fp); err != nil { fp.Close() os.Remove(fp.Name()) rs.logDebug("replValueStore: error caching ring %q: %s", rs.ringCachePath, err) } else { fp.Close() if err := os.Rename(fp.Name(), rs.ringCachePath); err != nil { os.Remove(fp.Name()) rs.logDebug("replValueStore: error caching ring %q: %s", rs.ringCachePath, err) } } } rs.ring = r var currentAddrs map[string]struct{} if r != nil { nodes := r.Nodes() currentAddrs = make(map[string]struct{}, len(nodes)) for _, n := range nodes { currentAddrs[n.Address(rs.addressIndex)] = struct{}{} } } var shutdownAddrs []string rs.storesLock.RLock() for a := range rs.stores { if _, ok := currentAddrs[a]; !ok { shutdownAddrs = append(shutdownAddrs, a) } } rs.storesLock.RUnlock() if len(shutdownAddrs) > 0 { shutdownStores := make([]*replValueStoreAndTicketChan, len(shutdownAddrs)) rs.storesLock.Lock() for i, a := range shutdownAddrs { shutdownStores[i] = rs.stores[a] rs.stores[a] = nil } rs.storesLock.Unlock() for i, s := range shutdownStores { if err := s.store.Shutdown(context.Background()); err != nil { rs.logDebug("replValueStore: error during shutdown of store %s: %s", shutdownAddrs[i], err) } } } rs.ringLock.Unlock() }
func persist(r ring.Ring, b *ring.Builder, filename string) error { dir, name := path.Split(filename) if dir == "" { dir = "." } f, err := ioutil.TempFile(dir, name+".") if err != nil { return err } tmp := f.Name() if r != nil { err = r.Persist(f) } else { err = b.Persist(f) } if err != nil { f.Close() return err } if err = f.Close(); err != nil { return err } return os.Rename(path.Join(dir, tmp), filename) }