From 617bbf52956ccd572ee424ab42b2e530a2eb664e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 13 Dec 2013 11:24:34 +0400 Subject: [PATCH] replica: support blobserver.Generationer Change-Id: Iad3a0e040fcffa7bee2cfe5ff7ce8904d4ded36c --- pkg/blobserver/replica/replica.go | 49 +++++++++++++++++++++++++++++++ pkg/server/root.go | 2 ++ 2 files changed, 51 insertions(+) diff --git a/pkg/blobserver/replica/replica.go b/pkg/blobserver/replica/replica.go index 4305ed3ed..6e76aa76f 100644 --- a/pkg/blobserver/replica/replica.go +++ b/pkg/blobserver/replica/replica.go @@ -35,12 +35,14 @@ Example config: package replica import ( + "bytes" "errors" "fmt" "io" "io/ioutil" "log" "net/http" + "time" "camlistore.org/pkg/blob" "camlistore.org/pkg/blobserver" @@ -48,6 +50,8 @@ import ( "camlistore.org/pkg/jsonconfig" ) +var _ blobserver.Generationer = (*replicaStorage)(nil) + const buffered = 8 type replicaStorage struct { @@ -258,6 +262,51 @@ func (sto *replicaStorage) EnumerateBlobs(ctx *context.Context, dest chan<- blob return blobserver.MergedEnumerate(ctx, dest, sto.readReplicas, after, limit) } +func (sto *replicaStorage) ResetStorageGeneration() error { + var ret error + n := 0 + for _, replica := range sto.replicas { + if g, ok := replica.(blobserver.Generationer); ok { + n++ + if err := g.ResetStorageGeneration(); err != nil && ret == nil { + ret = err + } + } + } + if n == 0 { + return errors.New("ResetStorageGeneration not supported") + } + return ret +} + +func (sto *replicaStorage) StorageGeneration() (initTime time.Time, random string, err error) { + var buf bytes.Buffer + n := 0 + for _, replica := range sto.replicas { + if g, ok := replica.(blobserver.Generationer); ok { + n++ + rt, rrand, rerr := g.StorageGeneration() + if rerr != nil { + err = rerr + } else { + if rt.After(initTime) { + // Returning the max of all initialization times. + // TODO: not sure whether max or min makes more sense. + initTime = rt + } + if buf.Len() != 0 { + buf.WriteByte('/') + } + buf.WriteString(rrand) + } + } + } + if n == 0 { + err = errors.New("No replicas support StorageGeneration") + } + return initTime, buf.String(), err +} + func init() { blobserver.RegisterStorageConstructor("replica", blobserver.StorageConstructor(newFromConfig)) } diff --git a/pkg/server/root.go b/pkg/server/root.go index 8de8426ff..d2cc7608c 100644 --- a/pkg/server/root.go +++ b/pkg/server/root.go @@ -182,6 +182,8 @@ func (rh *RootHandler) serveDiscovery(rw http.ResponseWriter, req *http.Request) m["storageInitTime"] = initTime.UTC().Format(time.RFC3339) m["storageGeneration"] = gen } + } else { + log.Printf("Storage type %T is not a blobserver.Generationer; not sending storageGeneration", rh.Storage) } if rh.ui != nil { rh.ui.populateDiscoveryMap(m)