예제 #1
0
파일: asgard.go 프로젝트: jgcsco/spigo
// 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
}
예제 #2
0
파일: asgard.go 프로젝트: jgcsco/spigo
// 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})
		}
	}
}