Example #1
0
// Start the app on the configured host/port.
//
// Supports graceful shutdown on 'kill' and 'int' signals.
func (app *App) Run() error {
	if app.vulcandReg != nil {
		err := app.vulcandReg.Start()
		if err != nil {
			return fmt.Errorf("failed to start vulcand registry: err=(%s)", err)
		}
		heartbeatCh := make(chan os.Signal, 1)
		signal.Notify(heartbeatCh, syscall.SIGUSR1)
		go func() {
			sig := <-heartbeatCh
			log.Infof("Got signal %v, canceling vulcand registration", sig)
			app.vulcandReg.Stop()
		}()
	}

	// listen for a shutdown signal
	exitCh := make(chan os.Signal, 1)
	signal.Notify(exitCh, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
	go func() {
		s := <-exitCh
		log.Infof("Got signal %v, shutting down", s)
		if app.vulcandReg != nil {
			app.vulcandReg.Stop()
		}
		manners.Close()
	}()

	addr := fmt.Sprintf("%v:%v", app.Config.ListenIP, app.Config.ListenPort)
	return manners.ListenAndServe(addr, app.router)
}
Example #2
0
// Start the app on the configured host/port.
//
// Supports graceful shutdown on 'kill' and 'int' signals.
func (app *App) Run() error {
	// toggle heartbeat on SIGUSR1
	go func() {
		app.heartbeater.Start()
		heartbeatChan := make(chan os.Signal, 1)
		signal.Notify(heartbeatChan, syscall.SIGUSR1)

		for s := range heartbeatChan {
			log.Infof("Received signal: %v, toggling heartbeat", s)
			app.heartbeater.Toggle()
		}
	}()

	// listen for a shutdown signal
	go func() {
		exitChan := make(chan os.Signal, 1)
		signal.Notify(exitChan, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
		s := <-exitChan
		log.Infof("Got shutdown signal: %v", s)
		manners.Close()
	}()

	addr := fmt.Sprintf("%v:%v", app.Config.ListenIP, app.Config.ListenPort)
	return manners.ListenAndServe(addr, app.router)
}
Example #3
0
func main() {
	startup := StartupConfig{}

	flag.StringVar(&startup.ConfigFile, "config", "/etc/servicegateway.json", "configuration file")
	flag.StringVar(&startup.DispatchingMode, "dispatch", "path", "dispatching mode ('path' or 'host')")
	flag.IntVar(&startup.Port, "port", 8080, "HTTP port to listen on")
	flag.BoolVar(&startup.Debug, "debug", false, "enable to add debug information to each request")
	flag.StringVar(&startup.ConsulBaseKey, "consul-base", "gateway/ui", "base key name for configuration")
	flag.StringVar(&startup.UiDir, "ui-dir", "/usr/share/servicegateway", "directory in which UI files can be found")
	flag.Parse()

	logger := logging.MustGetLogger("startup")
	format := logging.MustStringFormatter("%{color}%{time:15:04:05.000} %{module:12s} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}")
	backend := logging.NewLogBackend(os.Stderr, "", 0)

	logging.SetBackend(logging.NewBackendFormatter(backend, format))
	logger.Info("Completed startup")

	cfg := config.Configuration{}
	data, err := ioutil.ReadFile(startup.ConfigFile)
	if err != nil {
		logger.Fatal(err)
	}

	err = json.Unmarshal(data, &cfg)
	if err != nil {
		logger.Fatal(err)
		panic(err)
	}

	logger.Debug("%s", cfg)

	consulConfig := api.DefaultConfig()
	consulConfig.Address = "consul.service.consul:8500"
	consulConfig.Datacenter = "dev"

	consulClient, err := api.NewClient(consulConfig)
	if err != nil {
		logger.Panic(err)
	}

	redisPool := redis.NewPool(func() (redis.Conn, error) {
		return redis.Dial("tcp", cfg.Redis)
	}, 8)

	handler := proxy.NewProxyHandler(logging.MustGetLogger("proxy"))

	listenAddress := fmt.Sprintf(":%d", startup.Port)
	done := make(chan bool)

	go func() {
		var lastIndex uint64 = 0
		var err error

		dispChan := make(chan dispatcher.Dispatcher)
		go func() {
			for disp := range dispChan {
				logger.Info("starting dispatcher on address %s", listenAddress)
				manners.ListenAndServe(listenAddress, disp)
			}
		}()

		for {
			var dispatcher dispatcher.Dispatcher

			if lastIndex > 0 {
				time.Sleep(30 * time.Second)
			}

			dispatcher, lastIndex, err = buildDispatcher(
				&startup,
				&cfg,
				consulClient,
				handler,
				redisPool,
				logger,
				lastIndex,
			)

			if err != nil {
				logger.Error(err.Error())
			} else {
				manners.Close()
				dispChan <- dispatcher
			}
		}
	}()

	logger.Info("waiting to die")
	<-done
}