Commits

npe committed 6b14d5d

significant rewrite of the locale code, start testing now

  • Participants
  • Parent commits 46b7146

Comments (0)

Files changed (5)

 	master.go\
 	run.go\
 	slave.go\
+	localcfg.go\
+	strongboxcfg.go\
 	#	graphviz.go\
 
 include $(GOROOT)/src/Make.cmd
 package main
 
 import (
-	"io/ioutil"
-	"log"
-	"net"
 	"os"
-	"strconv"
+	"sync"
 )
 
-func getOurIPs() []string {
-	hostName, err := os.Hostname()
-	if err != nil {
-		log.Exit(err)
-	}
-	if addrs, ok := hostMap[hostName]; ok {
-		return addrs
-	}
-	_, addrs, err := net.LookupHost(hostName)
-	if err != nil {
-		log.Exit(err)
-	}
-	return addrs
-}
-
 /*
 
-so how does this get set up?
-what ron is actually doing is take something that should be an interface. 
+locales are a way of setting up arbitrary topologies given a known network. 
+They don't use hadoop style configuration files because many times you want to compute your network topology not derive it from a file. 
 
+This allows an abstract interface for gproc to interact with ad hoc trees.
+
+We also provide a json setup for static topologies as well.
+
+To add your own cluster to gproc you need to implement the Locale interface. 
 
 */
 
 
 type Locale interface {
 	Init(role string)
+	ParentCmdSocket() string
+	CmdSocket() string
+	RegisterServer(l Listener) (err os.Error)
 }
 
-var locales = map[string]Locale{
-	"local":     &local{},
-	"strongbox": &strongbox{},
+func init() {
+	
 }
 
-type local struct{}
+var locales map[string]Locale
 
-func (l local) Init(role string) {
-	switch role {
-	case "master", "slave":
-		cmd, err := ioutil.ReadFile(srvAddr)
-		if err != nil {
-			log.Exit(err)
-		}
-		parentCmdSocket = "127.0.0.1:" + string(cmd)
-	case "client", "run":
-	}
+var once sync.Once
+
+func addLocale(name string, loc Locale) {
+	once.Do(func() {
+		locales = make(map[string]Locale)
+	})
+	locales[name] = loc
 }
 
-type strongbox struct {
-}
+var parentCmdSocket = "0.0.0.0:0"
+var myCmdSocket = "0.0.0.0:0"
 
-func (l strongbox) Init(role string) {
-		/* set up hostMap */
-		hostMap = make(map[string][]string)
-		for i := 0; i < 197; i++ {
-			n := strconv.Itoa(i)
-			host := "cn" + n
-			ip := "10.0.0." + n
-			hostMap[host] = []string{ip}
-		}
-		addrs := getOurIPs()
-		switch role {
-		case "master":
-			cmdPort = "6666"
-			/* we hardwire this because the LocalAddr of a 
-			 * connected socket has an address of 0.0.0.0 !!
-			 */
-			myCmdSocket = "10.0.0.254:" + cmdPort
-			parentCmdSocket = ""
-		case "slave":
-			cmdPort = "6666"
-			/* on strongbox there's only ever one.
-			 * pick out the lowest-level octet.
-			 */
-			b := net.ParseIP(addrs[0]).To4()
-			which := b[3]
-			switch {
-			case which%7 == 0:
-				parentCmdSocket = "10.0.0.254:6666"
-			default:
-				boardMaster := ((which + 6) / 7) * 7
-				parentCmdSocket = "10.0.0." + string(boardMaster) + ":6666"
-			}
-			myCmdSocket = b.String() + cmdPort
-		case "client", "run":
-		}
-}
 
+
 	/* they are intended to be modified as needed by localInit */
 	defaultFam = "tcp4" /* arguably you might make this an option but it's kind of useless to do so */
 	cmdPort = "0"
-	parentCmdSocket = "0.0.0.0:0"
-	myCmdSocket = "0.0.0.0:0"
 	/* covering for issues in Go libraries */
 	/* net.LookUpHost fails if there is no DNS -- an incorrect behavior. On some locales (strongbox)
 	* you can load this up with cn hostnames. On Jaguar, may be impractical. 
 	 */
-	hostMap map[string][]string
 )
 
 func main() {
 			flag.Usage()
 		}
 		role = "master"
-		locales[role].Init(role)
-		startMaster(*defaultMasterUDS)
+		l := locales[*locale]
+		l.Init(role)
+		startMaster(*defaultMasterUDS, l)
 	case "WORKER", "worker", "s":
 		/* traditional slave; connect to master, await instructions */
 		if len(flag.Args()) != 1 {
 			flag.Usage()
 		}
 		role = "slave"
-		locales[role].Init(role)
-		startSlave(defaultFam, parentCmdSocket)
+		l := locales[*locale]
+		l.Init(role)
+		
+		startSlave(defaultFam, l.ParentCmdSocket(), l)
 	case "EXEC", "exec", "e":
 		if len(flag.Args()) < 3 {
 			flag.Usage()
 		}
 		role = "client"
-		locales[role].Init(role)
+		locales[*locale].Init(role)
 		startExecution(*defaultMasterUDS, defaultFam, *ioProxyPort, flag.Arg(1), flag.Args()[2:])
 	case "RUN", "run", "R":
 		role = "run"
-		locales[role].Init(role)
+		locales[*locale].Init(role)
 		run()
 	default:
 		flag.Usage()
 	"os"
 	"log"
 	"fmt"
-	"io/ioutil"
 	"strings"
 )
 
 	netaddr = ""
 )
 
-func startMaster(domainSock string) {
+func startMaster(domainSock string, loc Locale) {
 	log.SetPrefix("master " + *prefix + ": ")
 	Dprintln(2, "starting master")
 
 	go receiveCmds(domainSock)
-	registerSlaves()
+	registerSlaves(loc)
 }
 
 func sendCommands(r *RpcClientServer, sendReq *StartReq) {
 }
 
 /* move this to common once Noah has merged. */
-func registerSlaves() os.Error {
-	l, err := Listen(defaultFam, myCmdSocket)
+func registerSlaves(loc Locale) os.Error {
+	l, err := Listen(defaultFam, loc.CmdSocket())
 	if err != nil {
 		log.Exit("listen error:", err)
 	}
 	Dprint(2, l.Addr())
-	if *locale == "local" {
-		/* take the port only -- the address shows as 0.0.0.0 */
-		addr := strings.Split(l.Addr().String(), ":", 2)
-		err = ioutil.WriteFile(srvAddr, []byte(addr[1]), 0644)
-		if err != nil {
-			log.Exit(err)
-		}
+	err = loc.RegisterServer(l)
+	if err != nil {
+		log.Exit(err)
 	}
+
 	slaves = newSlaves()
 	for {
 		vd := &vitalData{}
  * up well for quite some time. And, in fact, it makes no sense to do it any other way ...
  */
 /* note that we're going to be able to merge master and slave fairly soon, now that they do almost the same things. */
-func startSlave(fam, masterAddr string) {
+func startSlave(fam, masterAddr string, loc Locale) {
 	/* slight difference from master: we're ready when we start, since we run things */
 	vitalData := &vitalData{HostReady: true}
 	/* some simple sanity checking */
 	vitalData.ParentAddr = client.RemoteAddr().String()
 	r := NewRpcClientServer(client)
 	initSlave(r, vitalData)
-	go registerSlaves()
+	go registerSlaves(loc)
 	for {
 		slaveProc(r)
 	}