From 5b1657a2d4b1b968f66a86637e2837a68ee30d5b Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 21 May 2011 13:40:17 -0700 Subject: [PATCH] Make blob storage constructors take a blobserver.Loader --- lib/go/camli/blobserver/localdisk/localdisk.go | 2 +- lib/go/camli/blobserver/registry.go | 15 ++++++++++++--- lib/go/camli/blobserver/remote/remote.go | 2 +- lib/go/camli/blobserver/s3/s3.go | 2 +- lib/go/camli/blobserver/shard/shard.go | 2 +- lib/go/camli/mysqlindexer/mysqlindexer.go | 2 +- server/go/camlistored/camlistored.go | 13 +++++++++++-- 7 files changed, 28 insertions(+), 10 deletions(-) diff --git a/lib/go/camli/blobserver/localdisk/localdisk.go b/lib/go/camli/blobserver/localdisk/localdisk.go index a1227140f..932cc280a 100644 --- a/lib/go/camli/blobserver/localdisk/localdisk.go +++ b/lib/go/camli/blobserver/localdisk/localdisk.go @@ -54,7 +54,7 @@ func New(root string) (storage *DiskStorage, err os.Error) { return } -func newFromConfig(config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { +func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { sto := &DiskStorage{ SimpleBlobHubPartitionMap: &blobserver.SimpleBlobHubPartitionMap{}, root: config.RequiredString("path"), diff --git a/lib/go/camli/blobserver/registry.go b/lib/go/camli/blobserver/registry.go index 5d379e5ea..e8bcc70a4 100644 --- a/lib/go/camli/blobserver/registry.go +++ b/lib/go/camli/blobserver/registry.go @@ -25,7 +25,16 @@ import ( "camli/jsonconfig" ) -type StorageConstructor func(config jsonconfig.Obj) (Storage, os.Error) +type Loader interface { + GetStorage(prefix string) (Storage, os.Error) +} + +type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, os.Error) + +// TODO: HandlerConstructor never ended up being used, but that was from +// before the Loader interface was introduced. Perhaps camlistored server +// could have all its non-Storage handlers simplified and no longer +// special-cased by using HandlerConstructor with a Loader parameter. type HandlerConstructor func(config jsonconfig.Obj) (http.Handler, os.Error) var mapLock sync.Mutex @@ -41,14 +50,14 @@ func RegisterStorageConstructor(typ string, ctor StorageConstructor) { storageConstructors[typ] = ctor } -func CreateStorage(typ string, config jsonconfig.Obj) (Storage, os.Error) { +func CreateStorage(typ string, loader Loader, config jsonconfig.Obj) (Storage, os.Error) { mapLock.Lock() ctor, ok := storageConstructors[typ] mapLock.Unlock() if !ok { return nil, fmt.Errorf("Storage type %q not known or loaded", typ) } - return ctor(config) + return ctor(loader, config) } func RegisterHandlerConstrutor(typ string, ctor HandlerConstructor) { diff --git a/lib/go/camli/blobserver/remote/remote.go b/lib/go/camli/blobserver/remote/remote.go index ddac29d18..ac0c68bdd 100644 --- a/lib/go/camli/blobserver/remote/remote.go +++ b/lib/go/camli/blobserver/remote/remote.go @@ -35,7 +35,7 @@ type remoteStorage struct { var _ = blobserver.Storage((*remoteStorage)(nil)) -func newFromConfig(config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { +func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { url := config.RequiredString("url") password := config.RequiredString("password") skipStartupCheck := config.OptionalBool("skipStartupCheck", false) diff --git a/lib/go/camli/blobserver/s3/s3.go b/lib/go/camli/blobserver/s3/s3.go index 41e7bdc0e..a87186987 100644 --- a/lib/go/camli/blobserver/s3/s3.go +++ b/lib/go/camli/blobserver/s3/s3.go @@ -32,7 +32,7 @@ type s3Storage struct { bucket string } -func newFromConfig(config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { +func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { client := &s3.Client{ Auth: &s3.Auth{ AccessKey: config.RequiredString("aws_access_key"), diff --git a/lib/go/camli/blobserver/shard/shard.go b/lib/go/camli/blobserver/shard/shard.go index edcc7ba6f..cee48891c 100644 --- a/lib/go/camli/blobserver/shard/shard.go +++ b/lib/go/camli/blobserver/shard/shard.go @@ -36,7 +36,7 @@ func (ss *shardStorage) GetBlobHub() blobserver.BlobHub { return ss.SimpleBlobHubPartitionMap.GetBlobHub() } -func newFromConfig(config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { +func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (storage blobserver.Storage, err os.Error) { sto := &shardStorage{ SimpleBlobHubPartitionMap: &blobserver.SimpleBlobHubPartitionMap{}, NoImplStorage: &blobserver.NoImplStorage{}, diff --git a/lib/go/camli/mysqlindexer/mysqlindexer.go b/lib/go/camli/mysqlindexer/mysqlindexer.go index 995206be6..8c4b0ca4f 100644 --- a/lib/go/camli/mysqlindexer/mysqlindexer.go +++ b/lib/go/camli/mysqlindexer/mysqlindexer.go @@ -43,7 +43,7 @@ type Indexer struct { cachedClients []*mysql.Client } -func newFromConfig(config jsonconfig.Obj) (blobserver.Storage, os.Error) { +func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (blobserver.Storage, os.Error) { indexer := &Indexer{ SimpleBlobHubPartitionMap: &blobserver.SimpleBlobHubPartitionMap{}, Host: config.OptionalString("host", "localhost"), diff --git a/server/go/camlistored/camlistored.go b/server/go/camlistored/camlistored.go index 4d26d90d4..cbe60931e 100644 --- a/server/go/camlistored/camlistored.go +++ b/server/go/camlistored/camlistored.go @@ -39,6 +39,7 @@ import ( // Storage options: _ "camli/blobserver/localdisk" + _ "camli/blobserver/remote" _ "camli/blobserver/s3" _ "camli/blobserver/shard" _ "camli/mysqlindexer" // indexer, but uses storage interface @@ -148,7 +149,7 @@ type handlerLoader struct { ws *webserver.Server baseURL string config map[string]*handlerConfig // prefix -> config - handler map[string]interface{} // prefix -> http.Handler / func + handler map[string]interface{} // prefix -> http.Handler / func / blobserver.Storage } func main() { @@ -260,6 +261,14 @@ func (hl *handlerLoader) getOrSetup(prefix string) interface{} { return hl.handler[prefix] } +func (hl *handlerLoader) GetStorage(prefix string) (blobserver.Storage, os.Error) { + hl.setupHandler(prefix) + if s, ok := hl.handler[prefix].(blobserver.Storage); ok { + return s, nil + } + return nil, fmt.Errorf("bogus storage handler referenced as %q", prefix) +} + func (hl *handlerLoader) setupHandler(prefix string) { h, ok := hl.config[prefix] if !ok { @@ -338,7 +347,7 @@ func (hl *handlerLoader) setupHandler(prefix string) { hl.ws.Handle(prefix, synch) default: // Assume a storage interface - pstorage, err := blobserver.CreateStorage(h.htype, h.conf) + pstorage, err := blobserver.CreateStorage(h.htype, hl, h.conf) if err != nil { exitFailure("error instantiating storage for prefix %q, type %q: %v", h.prefix, h.htype, err)