root: lazily load the search handler as needed. Don't block start-up.

This means we can prevent cycles elsewhere in load.

Change-Id: I670b7563b50818ef489a7f2fc832489e4bc659c8
This commit is contained in:
Brad Fitzpatrick 2013-01-11 10:35:19 -08:00
parent 5998fecc22
commit 446f03619c
2 changed files with 29 additions and 5 deletions

View File

@ -19,8 +19,10 @@ package server
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os/user"
"sync"
"time"
"camlistore.org/pkg/auth"
@ -43,11 +45,19 @@ type RootHandler struct {
SearchRoot string
Storage blobserver.Storage // of BlobRoot, or nil
Search *search.Handler // of SearchRoot, or nil
searchInitOnce sync.Once // runs searchInit, which populates searchHandler
searchInit func()
searchHandler *search.Handler // of SearchRoot, or nil
ui *UIHandler // or nil, if none configured
}
func (rh *RootHandler) SearchHandler() (h *search.Handler, ok bool) {
rh.searchInitOnce.Do(rh.searchInit)
return rh.searchHandler, rh.searchHandler != nil
}
func init() {
blobserver.RegisterHandlerConstructor("root", newRootFromConfig)
}
@ -75,9 +85,23 @@ func newRootFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handle
root.Storage = bs
}
root.searchInit = func() {}
if root.SearchRoot != "" {
h, _ := ld.GetHandler(root.SearchRoot)
root.Search = h.(*search.Handler)
prefix := root.SearchRoot
if t := ld.GetHandlerType(prefix); t != "search" {
if t == "" {
return nil, fmt.Errorf("root handler's searchRoot of %q is invalid and doesn't refer to a declared handler", prefix)
}
return nil, fmt.Errorf("root handler's searchRoot of %q is of type %q, not %q", prefix, t, "search")
}
root.searchInit = func() {
h, err := ld.GetHandler(prefix)
if err != nil {
log.Fatalf("Error fetching SearchRoot at %q: %v", prefix, err)
}
root.searchHandler = h.(*search.Handler)
root.searchInit = nil
}
}
return root, nil

View File

@ -287,8 +287,8 @@ func (ui *UIHandler) populateDiscoveryMap(m map[string]interface{}) {
"prefix": []string{key},
// TODO: include gpg key id
}
if ui.root.Search != nil {
pn, err := ui.root.Search.Index().PermanodeOfSignerAttrValue(ui.root.Search.Owner(), "camliRoot", pubh.RootName)
if sh, ok := ui.root.SearchHandler(); ok {
pn, err := sh.Index().PermanodeOfSignerAttrValue(sh.Owner(), "camliRoot", pubh.RootName)
if err == nil {
m["currentPermanode"] = pn.String()
}