示例#1
0
文件: server.go 项目: lichia/hydra
// Process a request coming from a client.
func (self *loadBalancer) processClient(client []byte, msg [][]byte) {
	// Application + Services + Instances
	if len(msg) < 3 {
		log.Fatal("Invalid message from client sender")
	}
	// Register chain
	self.registerChain(client, msg)
	// Start chain of requests
	self.advanceShackle(self.chains[string(client)])
}
示例#2
0
文件: server.go 项目: lichia/hydra
// Dispatch requests to waiting workers as possible
func (self *loadBalancer) dispatch(service *lbService, msg [][]byte) {
	if service == nil {
		log.Fatal("Nil service")
	}
	// Queue message if any
	if len(msg) != 0 {
		service.requests = append(service.requests, msg)
	}
	self.purgeWorkers()
	for service.waiting.Len() > 0 && len(service.requests) > 0 {
		msg, service.requests = service.requests[0], service.requests[1:]
		elem := service.waiting.Pop()
		self.waiting.Delete(elem.Value)
		worker, _ := elem.Value.(*lbWorker)

		self.sendToWorker(worker, SIGNAL_REQUEST, nil, msg)
	}
}
示例#3
0
文件: server.go 项目: lichia/hydra
// Main broker working loop
func (self *loadBalancer) Run() {
	for {
		items := zmq.PollItems{
			zmq.PollItem{Socket: self.frontend, Events: zmq.POLLIN},
			zmq.PollItem{Socket: self.backend, Events: zmq.POLLIN},
		}

		_, err := zmq.Poll(items, HEARTBEAT_INTERVAL)
		if err != nil {
			log.Fatal("Non items for polling")
		}

		if items[0].REvents&zmq.POLLIN != 0 {
			msg, _ := self.frontend.RecvMultipart(0)
			// TODO: check msg parts
			requestId := msg[0]
			msg = msg[2:]
			self.processClient(requestId, msg)
		}
		if items[1].REvents&zmq.POLLIN != 0 {
			msg, _ := self.backend.RecvMultipart(0)
			sender := msg[0]
			msg = msg[2:]
			self.processWorker(sender, msg)
		}

		if self.heartbeatAt.Before(time.Now()) {
			self.purgeWorkers()
			for elem := self.waiting.Front(); elem != nil; elem = elem.Next() {
				worker, _ := elem.Value.(*lbWorker)
				self.sendToWorker(worker, SIGNAL_HEARTBEAT, nil, nil)
			}
			self.heartbeatAt = time.Now().Add(HEARTBEAT_INTERVAL)
		}
	}
}
示例#4
0
文件: hydra.go 项目: lichia/hydra
func main() {
	// Load configuration.
	var conf = config.New()
	if err := conf.Load(os.Args[1:]); err != nil {
		log.Fatal(err.Error() + "\n")
	}

	// Enable verbose option.
	if conf.Verbose {
		log.Verbose = true
	}

	if conf.DataDir == "" {
		log.Fatal("Data dir does't exist")
	}

	// Create data directory if it doesn't already exist.
	if err := os.MkdirAll(conf.DataDir, 0744); err != nil {
		log.Fatalf("Unable to create path: %s", err)
	}

	// Load etcd configuration.
	if err := conf.LoadEtcdConfig(); err != nil {
		log.Fatalf("Unable to load etcd conf: %s", err)
	}

	// Launch services
	var etcd = etcd.New(conf.EtcdConf)
	etcd.Load()
	hydraEnv := os.Getenv("HYDRA_ENV")
	if hydraEnv == "ETCD_TEST" {
		etcd.Start(true)
	} else {
		go func() {
			var withEtcdServer bool = false
			if conf.EtcdAddr != "" {
				withEtcdServer = true
			}
			etcd.Start(withEtcdServer)
		}()

		connector.SetEtcdConnector(etcd)

		// Private Server API
		privateHydraListener, err := net.Listen("tcp", conf.PrivateAddr)
		if err != nil {
			log.Fatalf("Failed to create hydra private listener: ", err)
		}
		var privateServer = server.NewPrivateServer(privateHydraListener, conf.InstanceExpirationTime)
		privateServer.RegisterHandlers()
		go func() {
			log.Infof("hydra private server [name %s, listen on %s, advertised url %s]", conf.Name, conf.PrivateAddr, "http://"+conf.PrivateAddr)
			log.Fatal(http.Serve(privateServer.Listener, privateServer.Router))
		}()

		// Public Server API
		var loadBalancerFrontendEndpoint string = "ipc://" + conf.Name + "-frontend.ipc"
		publicHydraListener, err := net.Listen("tcp", conf.PublicAddr)
		if err != nil {
			log.Fatalf("Failed to create hydra public listener: ", err)
		}
		var publicServer = server.NewPublicServer(publicHydraListener, loadBalancerFrontendEndpoint, conf.BalanceTimeout)
		publicServer.RegisterHandlers()
		go func() {
			log.Infof("hydra public server [name %s, listen on %s, advertised url %s]", conf.Name, conf.PublicAddr, "http://"+conf.PublicAddr)
			log.Fatal(http.Serve(publicServer.Listener, publicServer.Router))
		}()

		// Load applications.
		var appsConfig = config.NewApplicationsConfig()
		if _, err := os.Stat(conf.AppsFile); os.IsNotExist(err) {
			log.Warnf("Unable to find apps file: %s", err)
		} else {
			if err := appsConfig.Load(conf.AppsFile); err != nil {
				log.Fatalf("Unable to load applications: %s", err)
			}
		}

		time.Sleep(1 * time.Second)
		// Persist Configured applications
		if err := appsConfig.Persists(); err != nil {
			log.Fatalf("Failed to save configured applications: ", err)
		}

		// Load Balancer
		loadBalancer := load_balancer.NewLoadBalancer(loadBalancerFrontendEndpoint, "tcp://"+conf.LoadBalancerAddr)
		defer loadBalancer.Close()
		loadBalancer.Run()
	}
}