Document blobserver.Loader methods, fix GetHandlerType to not force-load, diagnose loops better.

Change-Id: I03e989267e80ad610d3877c97fbf8adc8a88bb60
This commit is contained in:
Brad Fitzpatrick 2013-01-11 12:42:07 -08:00
parent 4be9f2f264
commit 88e92a6cc5
3 changed files with 22 additions and 6 deletions

View File

@ -2,7 +2,7 @@ all:
go install --tags=with_sqlite ./pkg/... ./server/... ./cmd/... ./third_party/...
presubmit:
SKIP_DEP_TESTS=1 go test -short ./pkg/... ./server/camlistored ./cmd/... && echo PASS
SKIP_DEP_TESTS=1 go test --tags=with_sqlite -short ./pkg/... ./server/camlistored ./cmd/... && echo PASS
embeds:
go install ./pkg/fileembed/genfileembed/ && genfileembed ./server/camlistored/ui

View File

@ -32,8 +32,15 @@ type FindHandlerByTyper interface {
// returns its prefix and handler if it's loaded. If it's not
// loaded, the error will be ErrHandlerTypeNotFound.
//
// This is used by handler constructors to find siblings (such as the "ui" type handler)
// This is used by handlers to find siblings (such as the "ui" type handler)
// which might have more knowledge about the configuration for discovery, etc.
//
// Note that if this is called during handler construction
// time, only the prefix may be returned with a nil handler
// and nil err. Unlike GetHandler and GetStorage, this does
// not cause the prefix to load immediately. At runtime (after
// construction of all handlers), then prefix and handler will
// both be non-nil when err is nil.
FindHandlerByType(handlerType string) (prefix string, handler interface{}, err error)
}
@ -43,12 +50,19 @@ type Loader interface {
// MyPrefix returns the prefix of the handler currently being constructed.
MyPrefix() string
GetStorage(prefix string) (Storage, error)
// GetHandlerType returns the handler's configured type, but does
// not force it to start being loaded yet.
GetHandlerType(prefix string) string // returns "" if unknown
// Returns either a Storage or an http.Handler
// GetHandler returns either a Storage or an http.Handler.
// It forces the handler to be loaded and returns an error if
// a cycle is created.
GetHandler(prefix string) (interface{}, error)
// GetStorage is like GetHandler but requires that the Handler be
// a storage Handler.
GetStorage(prefix string) (Storage, error)
// If we're loading configuration in response to a web request
// (as we do with App Engine), then this returns a request and
// true.

View File

@ -26,6 +26,7 @@ import (
"log"
"net/http"
"os"
"runtime"
"strconv"
"strings"
@ -225,7 +226,6 @@ func (hl *handlerLoader) GetHandler(prefix string) (interface{}, error) {
}
func (hl *handlerLoader) GetHandlerType(prefix string) string {
hl.setupHandler(prefix)
return hl.configType(prefix)
}
@ -247,7 +247,9 @@ func (hl *handlerLoader) setupHandler(prefix string) {
return
}
if h.settingUp {
exitFailure("loop in configuration graph; %q tried to load itself indirectly", prefix)
buf := make([]byte, 1024)
buf = buf[:runtime.Stack(buf, false)]
exitFailure("loop in configuration graph; %q tried to load itself indirectly. Stack:\n%s", prefix, buf)
}
h.settingUp = true
defer func() {