Beispiel #1
0
func main() {
	flag.Parse()
	wl, err := whiplash.New(*whipconf, true)
	if err != nil {
		log.Fatalf("error reading configuration file: %v\n", err)
	}
	sigchan := whiplash.AppSetup("whiplash-client", "0.1.0", pclient.Pkgname, pclient.Version)
	defer whiplash.AppCleanup("whiplash-client")

	// need a pclient configuration to talk to the aggregator with
	pcconf = &pclient.Config{
		Addr:    wl.Aggregator.BindAddr + ":" + wl.Aggregator.BindPort,
		Timeout: wl.Client.Timeout,
	}

	// decide what notification interval to use
	rand.Seed(time.Now().UnixNano())
	intv = rand.Intn(len(intvs))
	log.Printf("using interval set: %q\n", intvs[intv])
	// create tickers and launch monitor funcs
	pingticker := time.NewTicker(time.Second * intvs[intv]["ping"])
	statticker := time.NewTicker(time.Second * intvs[intv]["stat"])
	go pingSvcs(wl.Svcs, pingticker.C)
	go statSvcs(wl.Svcs, statticker.C)

	// mainloop
	keepalive := true
	for keepalive {
		select {
		case <-sigchan:
			// we've trapped a signal from the OS. tell our Asock to
			// shut down, but don't exit the eventloop because we want
			// to handle the Msgs which will be incoming.
			log.Println("OS signal received; shutting down")
			keepalive = false
		}
		// there's no default case in the select, as that would cause
		// it to be nonblocking. and that would cause main() to exit
		// immediately.
	}
}
Beispiel #2
0
func main() {
	// parse flags
	flag.Parse()
	// read the whiplash configuration
	wl, err := whiplash.New(*whipconf, false)
	if err != nil {
		log.Fatalf("error reading configuration file: %v\n", err)
	}
	// and do application initialization
	sigchan := whiplash.AppSetup("whiplash-aggregator", "0.1.1", petrel.Pkgname, petrel.Version)
	defer whiplash.AppCleanup("whiplash-aggregator")

	// setup the client petrel instance. first set the msglvl, then
	// instantiate the petrel.
	phconf := &petrel.Config{
		Sockname: wl.Aggregator.BindAddr + ":" + wl.Aggregator.BindPort,
		Msglvl:   msglvl[wl.Aggregator.MsgLvl],
		Timeout:  wl.Aggregator.Timeout,
	}
	cph, err := petrel.NewTCP(phconf)
	if err != nil {
		log.Fatal(err)
	}
	// and add command handlers to the petrel instance
	handlers := map[string]petrel.DispatchFunc{
		"ping": pingHandler,
		"stat": statHandler,
	}
	for name, handler := range handlers {
		err = cph.AddFunc(name, "nosplit", handler)
		if err != nil {
			log.Fatal(err)
		}
	}
	log.Println("client petrel instantiated")

	// now setup the query petrel instance
	phconf = &petrel.Config{
		Sockname: wl.Aggregator.BindAddr + ":" + wl.Aggregator.QueryPort,
		Msglvl:   msglvl[wl.Aggregator.MsgLvl],
		Timeout:  wl.Aggregator.QTimeout,
	}
	qph, err := petrel.NewTCP(phconf)
	if err != nil {
		log.Fatal(err)
	}
	// add command handlers to the query petrel instance
	handlers = map[string]petrel.DispatchFunc{
		"echo": qhEcho,
	}
	for name, handler := range handlers {
		err = qph.AddFunc(name, "split", handler)
		if err != nil {
			log.Fatal(err)
		}
	}
	log.Println("query petrel instantiated")

	// create a channel for the client petrel Msgr handler
	msgchan := make(chan error, 1)
	// and one for the query Msgr handler
	querychan := make(chan error, 1)
	// and launch them
	go msgHandler(cph, msgchan)
	go msgHandler(qph, querychan)
	log.Println("aggregator now listening")

	// this is the mainloop of the application.
	keepalive := true
	for keepalive {
		select {
		case msg := <-msgchan:
			// we've been handed a Msg over msgchan, which means that
			// our Handler has shut itself down for some reason. if this
			// were a more robust server, we would modularize Handler
			// creation and this eventloop, so that should we trap a
			// 599 we could spawn a new Handler and launch it in this
			// one's place. but we're just gonna exit this loop,
			// causing main() to terminate, and with it the server
			// instance.
			log.Println("Handler has shut down. Last Msg received was:")
			log.Println(msg)
			keepalive = false
			break
		case msg := <-querychan:
			// the query handler has died. it should be safe to
			// restart.
			log.Println("Query handler  has shut down. Last Msg received was:")
			log.Println(msg)
			log.Println("Restarting query petrel...")
			// TODO what it says ^^there
		case <-sigchan:
			// we've trapped a signal from the OS. tell our Petrel to
			// shut down, but don't exit the eventloop because we want
			// to handle the Msgs which will be incoming.
			log.Println("OS signal received; shutting down")
			cph.Quit()
		}
		// there's no default case in the select, as that would cause
		// it to be nonblocking. and that would cause main() to exit
		// immediately.
	}
}
Beispiel #3
0
func main() {
	flag.Parse()
	args = flag.Args()
	// read whiplash config. genconf should be FALSE in the
	// whiplash.New call for a wlq instance: we don't expect to hacve
	// ceph services around on a machine running a query.
	wl, err := whiplash.New(whipconf, false)
	if err != nil {
		quit(fmt.Errorf("can't read configuration file: %s\n", err))
	}

	// validate user input
	err = validateInput()
	if err != nil {
		quit(err)
	}
	// handle non-networked commands
	switch args[0] {
	case "help":
		showHelp()
		quit(nil)
	case "version":
		showVersion()
		quit(nil)
	}

	// set up configuration and create aclient instance
	pcconf := &pclient.Config{
		Addr:    wl.Aggregator.BindAddr + ":" + wl.Aggregator.QueryPort,
		Timeout: 100,
	}
	c, err := pclient.NewTCP(pcconf)
	if err != nil {
		quit(fmt.Errorf("can't connect to aggregator: %s", err))
	}
	defer c.Close()

	// stitch together the non-option arguments into our request
	req := strings.Join(flag.Args(), " ")
	// and dispatch it to the server!
	respj, err := c.Dispatch([]byte(req))
	if err != nil {
		quit(fmt.Errorf("sending request to aggregator failed: %s", err))
	}

	// vivify response and handle errors
	resp := new(whiplash.QueryResponse)
	err = json.Unmarshal(respj, &resp)
	if err != nil {
		quit(fmt.Errorf("failure unmarshaling json\nerror: %s\njson: %s", err, string(respj)))
	}
	if resp.Code >= 400 {
		quit(fmt.Errorf("there was a problem with the request:\n%s", string(respj)))
	}

	// if -j has been specified, print the raw response data and exit
	if dumpjson {
		fmt.Println(string(resp.Data))
		os.Exit(0)
	}

	// else, we have to hand off to a pretty-printing routine
	// TODO write a pretty-printing routine
}