From 1e844d505ac1928a0da40a5ef033baefe51da8cc Mon Sep 17 00:00:00 2001 From: John Date: Wed, 29 Apr 2020 00:14:29 +0800 Subject: [PATCH] comment update for package ghttp/gconv; readme update --- README.MD | 2 +- README_ZH.MD | 8 +- net/ghttp/ghttp_func.go | 4 + net/ghttp/ghttp_request_middleware.go | 4 + net/ghttp/ghttp_server.go | 109 +++++++++++++------------- util/gconv/gconv.go | 2 +- util/gconv/gconv_unsafe.go | 4 +- 7 files changed, 70 insertions(+), 63 deletions(-) diff --git a/README.MD b/README.MD index 2c46baf2c..67cc4e7e8 100644 --- a/README.MD +++ b/README.MD @@ -9,7 +9,7 @@ English | [简体中文](README_ZH.MD) -`GF(GoFrame)` is a modular, high-performance and production-ready application development framework +`GF(GoFrame)` is a modular, powerful, high-performance and production-ready application development framework of golang. Providing a series of core components and dozens of practical modules, such as: cache, logging, containers, timer, resource, validator, database orm, etc. Supporting web server integrated with router, cookie, session, middleware, logger, configure, diff --git a/README_ZH.MD b/README_ZH.MD index a9ae9c171..38a9ef5be 100644 --- a/README_ZH.MD +++ b/README_ZH.MD @@ -18,13 +18,13 @@ # 特点 * 模块化、松耦合设计; -* 模块丰富,开箱即用; -* 简便易用,易于维护; -* 社区活跃,大牛谦逊低调脾气好; +* 模块丰富、开箱即用; +* 简便易用、易于维护; * 高代码质量、高单元测试覆盖率; +* 社区活跃,大牛谦逊低调脾气好; * 详尽的开发文档及示例; * 完善的本地中文化支持; -* 更适合企业及团队使用; +* 设计为团队及企业使用; # 地址 - **主库**:https://github.com/gogf/gf diff --git a/net/ghttp/ghttp_func.go b/net/ghttp/ghttp_func.go index a48f0fa7f..26d32e45e 100644 --- a/net/ghttp/ghttp_func.go +++ b/net/ghttp/ghttp_func.go @@ -61,8 +61,12 @@ func niceCallFunc(f func()) { return default: if _, ok := e.(gerror.ApiStack); ok { + // It's already an error that has stack info. panic(e) } else { + // Create a new error with stack info. + // Note that there's a skip pointing the start stacktrace + // of the real error point. panic(gerror.NewfSkip(1, "%v", e)) } } diff --git a/net/ghttp/ghttp_request_middleware.go b/net/ghttp/ghttp_request_middleware.go index 8e751b329..813836cc4 100644 --- a/net/ghttp/ghttp_request_middleware.go +++ b/net/ghttp/ghttp_request_middleware.go @@ -122,8 +122,12 @@ func (m *Middleware) Next() { } }, func(exception interface{}) { if e, ok := exception.(gerror.ApiStack); ok { + // It's already an error that has stack info. m.request.error = e.(error) } else { + // Create a new error with stack info. + // Note that there's a skip pointing the start stacktrace + // of the real error point. m.request.error = gerror.NewfSkip(1, "%v", exception) } m.request.Response.WriteStatus(http.StatusInternalServerError, exception) diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go index c989942e0..91c0f6330 100644 --- a/net/ghttp/ghttp_server.go +++ b/net/ghttp/ghttp_server.go @@ -179,29 +179,21 @@ func init() { } } -// 主要用于开发者在HTTP处理中自定义异常捕获时,判断捕获的异常是否Server抛出的自定义退出异常 -func IsExitError(err interface{}) bool { - errStr := gconv.String(err) - if strings.EqualFold(errStr, gEXCEPTION_EXIT) || - strings.EqualFold(errStr, gEXCEPTION_EXIT_ALL) || - strings.EqualFold(errStr, gEXCEPTION_EXIT_HOOK) { - return true - } - return false -} - -// 是否开启平滑重启特性 +// SetGraceful enables/disables the graceful reload feature for server, +// which is false in default. +// +// Note that this feature switch is not for single server instance but for whole process. func SetGraceful(enabled bool) { gracefulEnabled = enabled } -// Web Server进程初始化. -// 注意该方法不能放置于包初始化方法init中,不使用ghttp.Server的功能便不能初始化对应的协程goroutine逻辑. +// serverProcessInit initializes some process configurations, which can only be done once. func serverProcessInit() { if !serverProcessInited.Cas(false, true) { return } - // 如果是完整重启,那么需要等待主进程销毁后,才开始执行监听,防止端口冲突 + // This means it is a restart server, it should kill its parent before starting its listening, + // to avoid duplicated port listening in two processes. if genv.Get(gADMIN_ACTION_RESTART_ENVKEY) != "" { if p, e := os.FindProcess(gproc.PPid()); e == nil { p.Kill() @@ -211,21 +203,24 @@ func serverProcessInit() { } } - // 信号量管理操作监听 + // Signal handler. go handleProcessSignal() - // 异步监听进程间消息 + + // Process message handler. + // It's enabled only graceful feature is enabled. if gracefulEnabled { go handleProcessMessage() } - // 是否处于开发环境,这里调用该方法初始化main包路径值, - // 防止异步服务goroutine获取main包路径失败, - // 该方法只有在main协程中才会执行。 + // It's an ugly calling for better initializing the main package path + // in source development environment. It is useful only be used in main goroutine. + // It fails retrieving the main package path in asynchronized goroutines. gfile.MainPkgPath() } -// 获取/创建一个默认配置的HTTP Server(默认监听端口是80) -// 单例模式,请保证name的唯一性 +// GetServer creates and returns a server instance using given name and default configurations. +// Note that the parameter should be unique for different servers. It returns an existing +// server instance if given is already existing in the server mapping. func GetServer(name ...interface{}) *Server { serverName := gDEFAULT_SERVER if len(name) > 0 && name[0] != "" { @@ -234,7 +229,6 @@ func GetServer(name ...interface{}) *Server { if s := serverMapping.Get(serverName); s != nil { return s.(*Server) } - c := Config() s := &Server{ name: serverName, plugins: make([]Plugin, 0), @@ -246,17 +240,17 @@ func GetServer(name ...interface{}) *Server { serveCache: gcache.New(), routesMap: make(map[string][]registeredRouteItem), } - // 初始化时使用默认配置 - if err := s.SetConfig(c); err != nil { + // Initialize the server using default configurations. + if err := s.SetConfig(Config()); err != nil { panic(err) } - // 记录到全局ServerMap中 + // Record the server to internal server mapping by name. serverMapping.Set(serverName, s) return s } -// 作为守护协程异步执行(当同一进程中存在多个Web Server时,需要采用这种方式执行), -// 需要结合Wait方式一起使用. +// Start starts listening on configured port. +// This function does not block the process, you can use function Wait blocking the process. func (s *Server) Start() error { // Register group routes. s.handlePreBindItems() @@ -481,14 +475,11 @@ func Wait() { glog.Printf("[ghttp] %d: all servers shutdown", gproc.Pid()) } -// 开启底层Web Server执行 +// startServer starts the underlying server listening. func (s *Server) startServer(fdMap listenerFdMap) { var httpsEnabled bool - // 判断是否启用HTTPS + // HTTPS if s.config.TLSConfig != nil || (s.config.HTTPSCertPath != "" && s.config.HTTPSKeyPath != "") { - // ================ - // HTTPS - // ================ if len(s.config.HTTPSAddr) == 0 { if len(s.config.Address) > 0 { s.config.HTTPSAddr = s.config.Address @@ -513,7 +504,8 @@ func (s *Server) startServer(fdMap listenerFdMap) { array := strings.Split(v, "#") if len(array) > 1 { itemFunc = array[0] - // windows系统不支持文件描述符传递socket通信平滑交接,因此只能完整重启 + // The windows OS does not support socket file descriptor passing + // from parent process. if runtime.GOOS != "windows" { fd = gconv.Int(array[1]) } @@ -526,10 +518,7 @@ func (s *Server) startServer(fdMap listenerFdMap) { s.servers[len(s.servers)-1].isHttps = true } } - // ================ // HTTP - // ================ - // 当HTTPS服务未启用时,默认HTTP地址才会生效 if !httpsEnabled && len(s.config.Address) == 0 { s.config.Address = gDEFAULT_HTTP_ADDR } @@ -548,7 +537,8 @@ func (s *Server) startServer(fdMap listenerFdMap) { array := strings.Split(v, "#") if len(array) > 1 { itemFunc = array[0] - // windows系统不支持文件描述符传递socket通信平滑交接,因此只能完整重启 + // The windows OS does not support socket file descriptor passing + // from parent process. if runtime.GOOS != "windows" { fd = gconv.Int(array[1]) } @@ -559,7 +549,7 @@ func (s *Server) startServer(fdMap listenerFdMap) { s.servers = append(s.servers, s.newGracefulServer(itemFunc)) } } - // 开始执行异步监听 + // Start listening asynchronizedly. serverRunning.Add(1) for _, v := range s.servers { go func(server *gracefulServer) { @@ -570,14 +560,13 @@ func (s *Server) startServer(fdMap listenerFdMap) { } else { err = server.ListenAndServe() } - // 如果非关闭错误,那么提示报错,否则认为是正常的服务关闭操作 + // The process exits if the server is closed with none closing error. if err != nil && !strings.EqualFold(http.ErrServerClosed.Error(), err.Error()) { s.Logger().Fatal(err) } - // 如果所有异步的http.Server都已经停止,那么WebServer就可以退出了 + // If all the underlying servers shutdown, the process exits. if s.serverCount.Add(-1) < 1 { s.closeChan <- struct{}{} - // 如果所有WebServer都退出,那么退出Wait等待 if serverRunning.Add(-1) < 1 { serverMapping.Remove(s.name) allDoneChan <- struct{}{} @@ -587,13 +576,12 @@ func (s *Server) startServer(fdMap listenerFdMap) { } } -// 获取当前服务器的状态 +// Status retrieves and returns the server status. func (s *Server) Status() int { - // 当全局运行的Web Server数量为0时表示所有Server都是停止状态 if serverRunning.Val() == 0 { return SERVER_STATUS_STOPPED } - // 只要有一个Server处于运行状态,那么都表示运行状态 + // If any underlying server is running, the server status is running. for _, v := range s.servers { if v.status == SERVER_STATUS_RUNNING { return SERVER_STATUS_RUNNING @@ -602,28 +590,39 @@ func (s *Server) Status() int { return SERVER_STATUS_STOPPED } -// 获取当前监听的文件描述符信息,构造成map返回 +// getListenerFdMap retrieves and returns the socket file descriptors. +// The key of the returned map is "http" and "https". func (s *Server) getListenerFdMap() map[string]string { m := map[string]string{ "https": "", "http": "", } - // s.servers是从HTTPS到HTTP优先级遍历,解析的时候也应当按照这个顺序读取fd for _, v := range s.servers { str := v.itemFunc + "#" + gconv.String(v.Fd()) + "," if v.isHttps { + if len(m["https"]) > 0 { + m["https"] += "," + } m["https"] += str } else { + if len(m["http"]) > 0 { + m["http"] += "," + } m["http"] += str } } - // 去掉末尾的","号 - if len(m["https"]) > 0 { - m["https"] = m["https"][0 : len(m["https"])-1] - } - if len(m["http"]) > 0 { - m["http"] = m["http"][0 : len(m["http"])-1] - } - return m } + +// IsExitError checks if given error is an exit error of server. +// This is used in old version of server for custom error handler. +// Deprecated. +func IsExitError(err interface{}) bool { + errStr := gconv.String(err) + if strings.EqualFold(errStr, gEXCEPTION_EXIT) || + strings.EqualFold(errStr, gEXCEPTION_EXIT_ALL) || + strings.EqualFold(errStr, gEXCEPTION_EXIT_HOOK) { + return true + } + return false +} diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index 594d21b39..0fc14ff18 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// Package gconv implements powerful and easy-to-use converting functionality for any types of variables. +// Package gconv implements powerful and convenient converting functionality for any types of variables. package gconv import ( diff --git a/util/gconv/gconv_unsafe.go b/util/gconv/gconv_unsafe.go index f5d327481..ce2f824f3 100644 --- a/util/gconv/gconv_unsafe.go +++ b/util/gconv/gconv_unsafe.go @@ -9,14 +9,14 @@ package gconv import "unsafe" // UnsafeStrToBytes converts string to []byte without memory copy. -// Note that, if you completely sure you will never use in the feature, +// Note that, if you completely sure you will never use variable in the feature, // you can use this unsafe function to implement type conversion in high performance. func UnsafeStrToBytes(s string) []byte { return *(*[]byte)(unsafe.Pointer(&s)) } // UnsafeBytesToStr converts []byte to string without memory copy. -// Note that, if you completely sure you will never use in the feature, +// Note that, if you completely sure you will never use variable in the feature, // you can use this unsafe function to implement type conversion in high performance. func UnsafeBytesToStr(b []byte) string { return *(*string)(unsafe.Pointer(&b))