blob: 7a8bb008881eb5edd9a37ef310353a1047b928c2 [file] [log] [blame]
package mounttable
import (
"sync"
"time"
"veyron2"
"veyron2/naming"
"veyron2/verror"
)
// namespace is an implementation of naming.MountTable.
type namespace struct {
sync.RWMutex
rt veyron2.Runtime
// the default root servers for resolutions in this namespace.
roots []string
}
func rooted(names []string) bool {
for _, n := range names {
if a, _ := naming.SplitAddressName(n); len(a) == 0 {
return false
}
}
return true
}
func badRoots(roots []string) verror.E {
return verror.BadArgf("At least one root is not a rooted name: %q", roots)
}
// Create a new namespace.
func New(rt veyron2.Runtime, roots ...string) (*namespace, error) {
if !rooted(roots) {
return nil, badRoots(roots)
}
// A namespace with no roots can still be used for lookups of rooted names.
return &namespace{rt: rt, roots: roots}, nil
}
// TODO(cnicolaou,caprita): make this a public interface.
// SetLocalRoots points the local roots at a set of mount table servers.
func (ns *namespace) SetLocalRoots(roots ...string) error {
if !rooted(roots) {
return badRoots(roots)
}
ns.Lock()
defer ns.Unlock()
ns.roots = roots
return nil
}
// rootName 'roots' a name: if name is not a rooted name, it prepends the root
// mounttable's OA.
func (ns *namespace) rootName(name string) []string {
if address, _ := naming.SplitAddressName(name); len(address) == 0 {
var ret []string
ns.RLock()
defer ns.RUnlock()
for _, r := range ns.roots {
ret = append(ret, naming.Join(r, name))
}
return ret
}
return []string{name}
}
// notAnMT returns true if the error indicates this isn't a mounttable server.
func notAnMT(err error) bool {
switch verror.ErrorID(err) {
case verror.BadArg:
// This should cover "ipc: wrong number of in-args".
return true
case verror.NotFound:
// This should cover "ipc: unknown method", "ipc: dispatcher not
// found", and "ipc: SoloDispatcher lookup on non-empty suffix".
return true
case verror.BadProtocol:
// This covers "ipc: response decoding failed: EOF".
return true
}
return false
}
// all operations against the mount table service use this fixed timeout for the
// time being.
const callTimeout = veyron2.CallTimeout(10 * time.Second)