github.com/nsqio/nsq@v1.3.0/apps/nsqlookupd/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"sync"
     9  	"syscall"
    10  
    11  	"github.com/BurntSushi/toml"
    12  	"github.com/judwhite/go-svc"
    13  	"github.com/mreiferson/go-options"
    14  	"github.com/nsqio/nsq/internal/lg"
    15  	"github.com/nsqio/nsq/internal/version"
    16  	"github.com/nsqio/nsq/nsqlookupd"
    17  )
    18  
    19  func nsqlookupdFlagSet(opts *nsqlookupd.Options) *flag.FlagSet {
    20  	flagSet := flag.NewFlagSet("nsqlookupd", flag.ExitOnError)
    21  
    22  	flagSet.String("config", "", "path to config file")
    23  	flagSet.Bool("version", false, "print version string")
    24  
    25  	logLevel := opts.LogLevel
    26  	flagSet.Var(&logLevel, "log-level", "set log verbosity: debug, info, warn, error, or fatal")
    27  	flagSet.String("log-prefix", "[nsqlookupd] ", "log message prefix")
    28  	flagSet.Bool("verbose", false, "[deprecated] has no effect, use --log-level")
    29  
    30  	flagSet.String("tcp-address", opts.TCPAddress, "<addr>:<port> to listen on for TCP clients")
    31  	flagSet.String("http-address", opts.HTTPAddress, "<addr>:<port> to listen on for HTTP clients")
    32  	flagSet.String("broadcast-address", opts.BroadcastAddress, "address of this lookupd node, (default to the OS hostname)")
    33  
    34  	flagSet.Duration("inactive-producer-timeout", opts.InactiveProducerTimeout, "duration of time a producer will remain in the active list since its last ping")
    35  	flagSet.Duration("tombstone-lifetime", opts.TombstoneLifetime, "duration of time a producer will remain tombstoned if registration remains")
    36  
    37  	return flagSet
    38  }
    39  
    40  type program struct {
    41  	once       sync.Once
    42  	nsqlookupd *nsqlookupd.NSQLookupd
    43  }
    44  
    45  func main() {
    46  	prg := &program{}
    47  	if err := svc.Run(prg, syscall.SIGINT, syscall.SIGTERM); err != nil {
    48  		logFatal("%s", err)
    49  	}
    50  }
    51  
    52  func (p *program) Init(env svc.Environment) error {
    53  	if env.IsWindowsService() {
    54  		dir := filepath.Dir(os.Args[0])
    55  		return os.Chdir(dir)
    56  	}
    57  	return nil
    58  }
    59  
    60  func (p *program) Start() error {
    61  	opts := nsqlookupd.NewOptions()
    62  
    63  	flagSet := nsqlookupdFlagSet(opts)
    64  	flagSet.Parse(os.Args[1:])
    65  
    66  	if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) {
    67  		fmt.Println(version.String("nsqlookupd"))
    68  		os.Exit(0)
    69  	}
    70  
    71  	var cfg config
    72  	configFile := flagSet.Lookup("config").Value.String()
    73  	if configFile != "" {
    74  		_, err := toml.DecodeFile(configFile, &cfg)
    75  		if err != nil {
    76  			logFatal("failed to load config file %s - %s", configFile, err)
    77  		}
    78  	}
    79  	cfg.Validate()
    80  
    81  	options.Resolve(opts, flagSet, cfg)
    82  	nsqlookupd, err := nsqlookupd.New(opts)
    83  	if err != nil {
    84  		logFatal("failed to instantiate nsqlookupd", err)
    85  	}
    86  	p.nsqlookupd = nsqlookupd
    87  
    88  	go func() {
    89  		err := p.nsqlookupd.Main()
    90  		if err != nil {
    91  			p.Stop()
    92  			os.Exit(1)
    93  		}
    94  	}()
    95  
    96  	return nil
    97  }
    98  
    99  func (p *program) Stop() error {
   100  	p.once.Do(func() {
   101  		p.nsqlookupd.Exit()
   102  	})
   103  	return nil
   104  }
   105  
   106  func logFatal(f string, args ...interface{}) {
   107  	lg.LogFatal("[nsqlookupd] ", f, args...)
   108  }