Make blob storage constructors take a blobserver.Loader

This commit is contained in:
Brad Fitzpatrick 2011-05-21 13:40:17 -07:00
parent 1c83320706
commit 5b1657a2d4
7 changed files with 28 additions and 10 deletions

View File

@ -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"),

View File

@ -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) {

View File

@ -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)

View File

@ -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"),

View File

@ -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{},

View File

@ -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"),

View File

@ -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)