main.go 2.7 KB

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