func (s *Session) Serve(d Dispatcher, maxPipeline int) { var errlist errors.ErrorList defer func() { log.Infof(Red("==> Session Over: %s, Print Error List: %d Errors"), s.RemoteAddress, errlist.Len()) // 只打印第一个Error if err := errlist.First(); err != nil { log.Infof("==> Session [%p] closed, Error = %v", s, err) } else { log.Infof("==> Session [%p] closed, Quit", s) } }() // 来自connection的各种请求 tasks := make(chan *Request, maxPipeline) go func() { defer func() { // 出现错误了,直接关闭Session s.Close() // 扔掉所有的Tasks log.Warnf(Red("Session Closed, Abandon %d Tasks"), len(tasks)) for task := range tasks { task.Recycle() } }() if err := s.loopWriter(tasks); err != nil { errlist.PushBack(err) } }() defer close(tasks) // 从Client读取用户的请求,然后再交给Dispatcher来处理 if err := s.loopReader(tasks, d); err != nil { errlist.PushBack(err) } log.Info(Cyan("LoopReader Over, Session#Serve Over")) }
func NewSessionSize(c thrift.TTransport, address string, verbose bool, bufsize int, timeout int) *Session { s := &Session{ CreateUnix: time.Now().Unix(), RemoteAddress: address, verbose: verbose, TBufferedFramedTransport: NewTBufferedFramedTransport(c, time.Microsecond*100, 20), } // Reader 处理Client发送过来的消息 // Writer 将后端服务的数据返回给Client log.Infof(Green("NewSession To: %s"), s.RemoteAddress) return s }
func setLogLevel(level string) { var lv = log.LEVEL_INFO switch strings.ToLower(level) { case "error": lv = log.LEVEL_ERROR case "warn", "warning": lv = log.LEVEL_WARN case "debug": lv = log.LEVEL_DEBUG case "info": fallthrough default: lv = log.LEVEL_INFO } log.SetLevel(lv) log.Infof("set log level to %s", lv) }
func RpcMain(binaryName string, serviceDesc string, configCheck ConfigCheck, serverFactory ServerFactorory, buildDate string, gitVersion string) { // 1. 准备解析参数 usage = fmt.Sprintf(usage, binaryName, binaryName) version := fmt.Sprintf("Version: %s\nBuildDate: %s\nDesc: %s\nAuthor: [email protected]", gitVersion, buildDate, serviceDesc) args, err := docopt.Parse(usage, nil, true, version, true) if err != nil { fmt.Println(err) os.Exit(1) } if s, ok := args["-V"].(bool); ok && s { fmt.Println(Green(version)) os.Exit(1) } // 这就是为什么 Codis 傻乎乎起一个 http server的目的 if s, ok := args["--profile-addr"].(string); ok && len(s) > 0 { go func() { log.Printf(Red("Profile Address: %s"), s) log.Println(http.ListenAndServe(s, nil)) }() } // 2. 解析Log相关的配置 log.SetLevel(log.LEVEL_INFO) var maxKeepDays int = 3 if s, ok := args["--log-keep-days"].(string); ok && s != "" { v, err := strconv.ParseInt(s, 10, 32) if err != nil { log.PanicErrorf(err, "invalid max log file keep days = %s", s) } maxKeepDays = int(v) } // set output log file if s, ok := args["-L"].(string); ok && s != "" { f, err := log.NewRollingFile(s, maxKeepDays) if err != nil { log.PanicErrorf(err, "open rolling log file failed: %s", s) } else { defer f.Close() log.StdLog = log.New(f, "") } } log.SetLevel(log.LEVEL_INFO) log.SetFlags(log.Flags() | log.Lshortfile) // set log level if s, ok := args["--log-level"].(string); ok && s != "" { SetLogLevel(s) } // 没有就没有 workDir, _ := args["--work-dir"].(string) codeUrlVersion, _ := args["--code-url-version"].(string) if len(workDir) == 0 { workDir, _ = os.Getwd() } log.Printf("WorkDir: %s, CodeUrl: %s, Wd: %s", workDir, codeUrlVersion) // 3. 解析Config configFile := args["-c"].(string) conf, err := utils.LoadConf(configFile) if err != nil { log.PanicErrorf(err, "load config failed") } // 额外的配置信息 conf.WorkDir = workDir conf.CodeUrlVersion = codeUrlVersion if configCheck != nil { configCheck(conf) } else { log.Panic("No Config Check Given") } // 每次启动的时候都打印版本信息 log.Infof(Green("-----------------\n%s\n--------------------------------------------------------------------"), version) // 启动服务 server := serverFactory(conf) server.Run() }