func (p *program) Start() error { flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) os.Exit(0) } var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } cfg.Validate() opts := nsqd.NewOptions() options.Resolve(opts, flagSet, cfg) nsqd := nsqd.New(opts) nsqd.LoadMetadata() err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() p.nsqd = nsqd return nil }
func (p *program) Start() error { //解析用户输入的命令 flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) //输出版本号并结束 if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) os.Exit(0) } //读取配置文件 var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } //验证配置文件 cfg.Validate() //载入默认配置选项 opts := nsqd.NewOptions() //整合配置选项(优先级:--???--) options.Resolve(opts, flagSet, cfg) //建立服务(载入基本配置) nsqd := nsqd.New(opts) //启动服务前 恢复数据(从硬盘载入数据) nsqd.LoadMetadata() //将内存中的数据写入到硬盘文件中 (创建新文件 保留旧文件--???--) err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() p.nsqd = nsqd return nil }
func main() { flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) return } signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } cfg.Validate() opts := nsqd.NewOptions() options.Resolve(opts, flagSet, cfg) nsqd := nsqd.New(opts) nsqd.LoadMetadata() err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() <-signalChan nsqd.Exit() }
// MAIN func main() { var err error app := cli.NewApp() app.Name = "tmail" app.Usage = "SMTP server" app.Author = "Stéphane Depierrepont aka toorop" app.Email = "*****@*****.**" app.Version = TmailVersion app.Commands = tcli.CliCommands // no know command ? Launch server app.Action = func(c *cli.Context) { if len(c.Args()) != 0 { cli.ShowAppHelp(c) } else { // if there is nothing to do then... do nothing if !core.Cfg.GetLaunchDeliverd() && !core.Cfg.GetLaunchSmtpd() { log.Fatalln("I have nothing to do, so i do nothing. Bye.") } // Init Bolt (used as cache) if err = core.InitBolt(); err != nil { log.Fatalln("Init bolt failed", err) } // Loop sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) // TODO // Chanel to comunicate between all elements //daChan := make(chan string) // init and launch nsqd opts := nsqd.NewOptions() opts.Logger = log.New(ioutil.Discard, "", 0) if core.Cfg.GetDebugEnabled() { opts.Logger = core.Log } opts.Verbose = core.Cfg.GetDebugEnabled() opts.DataPath = core.GetBasePath() + "/nsq" // if cluster get lookupd addresses if core.Cfg.GetClusterModeEnabled() { opts.NSQLookupdTCPAddresses = core.Cfg.GetNSQLookupdTcpAddresses() } // deflate (compression) opts.DeflateEnabled = true // if a message timeout it returns to the queue: https://groups.google.com/d/msg/nsq-users/xBQF1q4srUM/kX22TIoIs-QJ // msg timeout : base time to wait from consummer before requeuing a message // note: deliverd consumer return immediatly (message is handled in a go routine) // Ce qui est au dessus est faux malgres la go routine il attends toujours a la réponse // et c'est normal car le message est toujours "in flight" // En fait ce timeout c'est le temps durant lequel le message peut rester dans le state "in flight" // autrement dit c'est le temps maxi que peu prendre deliverd.processMsg opts.MsgTimeout = 10 * time.Minute // maximum duration before a message will timeout opts.MaxMsgTimeout = 15 * time.Hour // maximum requeuing timeout for a message // si le client ne demande pas de requeue dans ce delais alors // le message et considéré comme traité opts.MaxReqTimeout = 1 * time.Hour // Number of message in RAM before synching to disk opts.MemQueueSize = 0 nsqd := nsqd.New(opts) nsqd.LoadMetadata() if err = nsqd.PersistMetadata(); err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() // smtpd if core.Cfg.GetLaunchSmtpd() { // clamav ? if core.Cfg.GetSmtpdClamavEnabled() { if err = core.NewClamav().Ping(); err != nil { log.Fatalln("Unable to connect to clamd -", err) } } smtpdDsns, err := core.GetDsnsFromString(core.Cfg.GetSmtpdDsns()) if err != nil { log.Fatalln("unable to parse smtpd dsn -", err) } for _, dsn := range smtpdDsns { go core.NewSmtpd(dsn).ListenAndServe() // TODO at this point we don't know if serveur is launched core.Log.Info("smtpd " + dsn.String() + " launched.") } } // deliverd go core.LaunchDeliverd() // HTTP REST server if core.Cfg.GetRestServerLaunch() { go rest.LaunchServer() } <-sigChan core.Log.Info("Exiting...") // close NsqQueueProducer if exists core.NsqQueueProducer.Stop() // flush nsqd memory to disk nsqd.Exit() // exit os.Exit(0) } } app.Run(os.Args) }