func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err error) { sto := &replicaStorage{ replicaPrefixes: config.RequiredList("backends"), readPrefixes: config.OptionalList("readBackends"), } nReplicas := len(sto.replicaPrefixes) sto.minWritesForSuccess = config.OptionalInt("minWritesForSuccess", nReplicas) if err := config.Validate(); err != nil { return nil, err } if nReplicas == 0 { return nil, errors.New("replica: need at least one replica") } if sto.minWritesForSuccess == 0 { sto.minWritesForSuccess = nReplicas } // readPrefixes defaults to the write prefixes. if len(sto.readPrefixes) == 0 { sto.readPrefixes = sto.replicaPrefixes } for _, prefix := range sto.replicaPrefixes { s, err := ld.GetStorage(prefix) if err != nil { // If it's not a storage interface, it might be an http Handler // that also supports being a target (e.g. a sync handler). h, _ := ld.GetHandler(prefix) var ok bool if s, ok = h.(blobserver.Storage); !ok { return nil, err } } sto.replicas = append(sto.replicas, s) } for _, prefix := range sto.readPrefixes { s, err := ld.GetStorage(prefix) if err != nil { return nil, err } sto.readReplicas = append(sto.readReplicas, s) } return sto, nil }
func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err error) { sto := &shardStorage{ shardPrefixes: config.RequiredList("backends"), } if err := config.Validate(); err != nil { return nil, err } if len(sto.shardPrefixes) == 0 { return nil, errors.New("shard: need at least one shard") } sto.shards = make([]blobserver.Storage, len(sto.shardPrefixes)) for i, prefix := range sto.shardPrefixes { shardSto, err := ld.GetStorage(prefix) if err != nil { return nil, err } sto.shards[i] = shardSto } return sto, nil }