// Create a tier and specify any dependencies, return the full name of the last node created func Create(servicename, packagename string, regions, count int, dependencies ...string) string { var name string arch := archaius.Conf.Arch rnames := archaius.Conf.RegionNames znames := archaius.Conf.ZoneNames if regions == 0 { // for dns that isn't in a region or zone //log.Printf("Create cross region: " + servicename) name = names.Make(arch, "*", "*", servicename, packagename, 0) StartNode(name, dependencies...) } for r := 0; r < regions; r++ { if count == 0 { // for AWS services that are cross zone like elb and S3 //log.Printf("Create cross zone: " + servicename) name = names.Make(arch, rnames[r], "*", servicename, packagename, 0) StartNode(name, dependencies...) } else { //log.Printf("Create service: " + servicename) cass := make(map[string]mapchan) // for token distribution for i := r * count; i < (r+1)*count; i++ { name = names.Make(arch, rnames[r], znames[i%len(archaius.Conf.ZoneNames)], servicename, packagename, i) //log.Println(dependencies) StartNode(name, dependencies...) if packagename == "priamCassandra" { rz := names.RegionZone(name) if cass[rz] == nil { cass[rz] = make(mapchan) } cass[rz][name] = noodles[name] // remember the nodes } } if packagename == "priamCassandra" { // split by zone for _, v := range cass { priamCassandra.Distribute(v) // returns a string if it needs logging } } } } return name }
// Start a node using the named package, and connect it to any dependencies func StartNode(name string, dependencies ...string) { if names.Package(name) == EurekaPkg { eurekachan[name] = make(chan gotocol.Message, archaius.Conf.Population/len(archaius.Conf.ZoneNames)) // buffer sized to a zone go eureka.Start(eurekachan[name], name) return } else { noodles[name] = make(chan gotocol.Message) } // start the service and tell it it's name switch names.Package(name) { case PiratePkg: go pirate.Start(noodles[name]) case ElbPkg: go elb.Start(noodles[name]) case DenominatorPkg: go denominator.Start(noodles[name]) case ZuulPkg: go zuul.Start(noodles[name]) case KaryonPkg: go karyon.Start(noodles[name]) case MonolithPkg: go monolith.Start(noodles[name]) case StaashPkg: go staash.Start(noodles[name]) case RiakPkg: fallthrough // fake Riak using priamCassandra case PriamCassandraPkg: go priamCassandra.Start(noodles[name]) case CachePkg: fallthrough // fake memcache using store case VolumePkg: fallthrough // fake disk volume using store case StorePkg: go store.Start(noodles[name]) default: log.Fatal("asgard: unknown package: " + names.Package(name)) } noodles[name] <- gotocol.Message{gotocol.Hello, listener, time.Now(), gotocol.NilContext, name} // there is a eureka service registry in each zone, so in-zone services just get to talk to their local registry // elb are cross zone, so need to see all registries in a region // denominator are cross region so need to see all registries globally // priamCassandra depends explicitly on eureka for cross region clusters crossregion := false for _, d := range dependencies { if d == "eureka" { crossregion = true } } for n, ch := range eurekachan { if names.Region(name) == "*" || crossregion { // need to know every eureka in all zones and regions gotocol.Send(noodles[name], gotocol.Message{gotocol.Inform, ch, time.Now(), gotocol.NilContext, n}) } else { if names.Zone(name) == "*" && names.Region(name) == names.Region(n) { // need every eureka in my region gotocol.Send(noodles[name], gotocol.Message{gotocol.Inform, ch, time.Now(), gotocol.NilContext, n}) } else { if names.RegionZone(name) == names.RegionZone(n) { // just the eureka in this specific zone gotocol.Send(noodles[name], gotocol.Message{gotocol.Inform, ch, time.Now(), gotocol.NilContext, n}) } } } } //log.Println(dependencies) // pass on symbolic dependencies without channels that will be looked up in Eureka later for _, dep := range dependencies { if dep != "" && dep != "eureka" { // ignore special case of eureka in dependency list //log.Println(name + " depends on " + dep) gotocol.Send(noodles[name], gotocol.Message{gotocol.NameDrop, nil, time.Now(), gotocol.NilContext, dep}) } } }