Files
gf/net/ghttp/ghttp_server_admin_process.go

306 lines
8.5 KiB
Go
Raw Normal View History

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package ghttp
import (
2019-06-19 09:06:52 +08:00
"bytes"
"context"
2019-06-19 09:06:52 +08:00
"fmt"
"os"
"runtime"
"strings"
"sync"
"time"
2019-07-29 21:01:19 +08:00
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/encoding/gjson"
2021-11-13 23:23:55 +08:00
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/internal/intlog"
"github.com/gogf/gf/v2/os/gfile"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/os/gtimer"
2021-11-13 23:23:55 +08:00
"github.com/gogf/gf/v2/text/gstr"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/util/gconv"
)
const (
2020-05-01 03:31:04 +08:00
// Allow executing management command after server starts after this interval in milliseconds.
2020-12-15 20:16:17 +08:00
adminActionIntervalLimit = 2000
adminActionNone = 0
adminActionRestarting = 1
adminActionShuttingDown = 2
adminActionReloadEnvKey = "GF_SERVER_RELOAD"
adminActionRestartEnvKey = "GF_SERVER_RESTART"
adminGProcCommGroup = "GF_GPROC_HTTP_SERVER"
)
2021-09-27 21:27:24 +08:00
var (
// serverActionLocker is the locker for server administration operations.
serverActionLocker sync.Mutex
2021-09-27 21:27:24 +08:00
// serverActionLastTime is timestamp in milliseconds of last administration operation.
serverActionLastTime = gtype.NewInt64(gtime.TimestampMilli())
2021-09-27 21:27:24 +08:00
// serverProcessStatus is the server status for operation of current process.
serverProcessStatus = gtype.NewInt()
)
// RestartAllServer restarts all the servers of the process gracefully.
// The optional parameter `newExeFilePath` specifies the new binary file for creating process.
func RestartAllServer(ctx context.Context, newExeFilePath string) error {
if !gracefulEnabled {
return gerror.NewCode(
gcode.CodeInvalidOperation,
"graceful reload feature is disabled",
)
}
2019-06-19 09:06:52 +08:00
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := checkProcessStatus(); err != nil {
return err
}
2020-05-01 03:31:04 +08:00
if err := checkActionFrequency(); err != nil {
2019-06-19 09:06:52 +08:00
return err
}
return restartWebServers(ctx, nil, newExeFilePath)
}
// ShutdownAllServer shuts down all servers of current process gracefully.
2021-09-27 21:27:24 +08:00
func ShutdownAllServer(ctx context.Context) error {
2019-06-19 09:06:52 +08:00
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := checkProcessStatus(); err != nil {
return err
}
2020-05-01 03:31:04 +08:00
if err := checkActionFrequency(); err != nil {
2019-06-19 09:06:52 +08:00
return err
}
shutdownWebServersGracefully(ctx, nil)
2019-06-19 09:06:52 +08:00
return nil
}
2020-05-01 03:31:04 +08:00
// checkProcessStatus checks the server status of current process.
func checkProcessStatus() error {
2019-06-19 09:06:52 +08:00
status := serverProcessStatus.Val()
if status > 0 {
switch status {
2020-12-15 20:16:17 +08:00
case adminActionRestarting:
return gerror.NewCode(gcode.CodeInvalidOperation, "server is restarting")
2021-07-20 23:02:02 +08:00
2020-12-15 20:16:17 +08:00
case adminActionShuttingDown:
return gerror.NewCode(gcode.CodeInvalidOperation, "server is shutting down")
2019-06-19 09:06:52 +08:00
}
}
return nil
}
2020-05-01 03:31:04 +08:00
// checkActionFrequency checks the operation frequency.
// It returns error if it is too frequency.
func checkActionFrequency() error {
interval := gtime.TimestampMilli() - serverActionLastTime.Val()
2020-12-15 20:16:17 +08:00
if interval < adminActionIntervalLimit {
2021-07-20 23:02:02 +08:00
return gerror.NewCodef(
gcode.CodeInvalidOperation,
2021-07-20 23:02:02 +08:00
"too frequent action, please retry in %d ms",
adminActionIntervalLimit-interval,
)
2019-06-19 09:06:52 +08:00
}
serverActionLastTime.Set(gtime.TimestampMilli())
2019-06-19 09:06:52 +08:00
return nil
}
2020-05-01 03:31:04 +08:00
// forkReloadProcess creates a new child process and copies the fd to child process.
2021-09-27 21:27:24 +08:00
func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error {
var (
binaryPath = os.Args[0]
2021-09-27 21:27:24 +08:00
)
2023-12-14 21:51:28 +08:00
if len(newExeFilePath) > 0 && newExeFilePath[0] != "" {
binaryPath = newExeFilePath[0]
}
if !gfile.Exists(binaryPath) {
return gerror.Newf(`binary file path "%s" does not exist`, binaryPath)
2019-06-19 09:06:52 +08:00
}
2020-05-01 03:31:04 +08:00
var (
p = gproc.NewProcess(binaryPath, os.Args[1:], os.Environ())
2020-05-01 03:31:04 +08:00
sfm = getServerFdMap()
)
2019-06-19 09:06:52 +08:00
for name, m := range sfm {
for fdk, fdv := range m {
if len(fdv) > 0 {
s := ""
for _, item := range gstr.SplitAndTrim(fdv, ",") {
2019-06-19 09:06:52 +08:00
array := strings.Split(item, "#")
fd := uintptr(gconv.Uint(array[1]))
if fd > 0 {
s += fmt.Sprintf("%s#%d,", array[0], 3+len(p.ExtraFiles))
p.ExtraFiles = append(p.ExtraFiles, os.NewFile(fd, ""))
} else {
s += fmt.Sprintf("%s#%d,", array[0], 0)
}
}
sfm[name][fdk] = strings.TrimRight(s, ",")
}
}
}
buffer, _ := gjson.Encode(sfm)
2020-12-15 20:16:17 +08:00
p.Env = append(p.Env, adminActionReloadEnvKey+"="+string(buffer))
if _, err := p.Start(ctx); err != nil {
intlog.Errorf(
2021-09-27 21:27:24 +08:00
ctx,
"%d: fork process failed, error: %s, %s",
2021-09-27 21:27:24 +08:00
gproc.Pid(), err.Error(), string(buffer),
)
2019-06-19 09:06:52 +08:00
return err
}
return nil
}
2020-05-01 03:31:04 +08:00
// forkRestartProcess creates a new server process.
2023-12-14 21:51:28 +08:00
func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error {
2021-09-27 21:27:24 +08:00
var (
path = os.Args[0]
)
2023-12-14 21:51:28 +08:00
if len(newExeFilePath) > 0 && newExeFilePath[0] != "" {
path = newExeFilePath[0]
2019-06-19 09:06:52 +08:00
}
2021-09-27 21:27:24 +08:00
if err := os.Unsetenv(adminActionReloadEnvKey); err != nil {
intlog.Errorf(ctx, `%+v`, err)
2021-09-27 21:27:24 +08:00
}
2019-06-19 09:06:52 +08:00
env := os.Environ()
2020-12-15 20:16:17 +08:00
env = append(env, adminActionRestartEnvKey+"=1")
p := gproc.NewProcess(path, os.Args[1:], env)
if _, err := p.Start(ctx); err != nil {
2021-09-27 21:27:24 +08:00
glog.Errorf(
ctx,
`%d: fork process failed, error:%s, are you running using "go run"?`,
gproc.Pid(), err.Error(),
)
2019-06-19 09:06:52 +08:00
return err
}
return nil
}
2020-05-01 03:31:04 +08:00
// getServerFdMap returns all the servers name to file descriptor mapping as map.
func getServerFdMap() map[string]listenerFdMap {
2019-06-19 09:06:52 +08:00
sfm := make(map[string]listenerFdMap)
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
serverMapping.RLockFunc(func(m map[string]any) {
2019-06-19 09:06:52 +08:00
for k, v := range m {
sfm[k] = v.(*Server).getListenerFdMap()
}
})
return sfm
}
2020-05-01 03:31:04 +08:00
// bufferToServerFdMap converts binary content to fd map.
func bufferToServerFdMap(buffer []byte) map[string]listenerFdMap {
2019-06-19 09:06:52 +08:00
sfm := make(map[string]listenerFdMap)
if len(buffer) > 0 {
j, _ := gjson.LoadContent(buffer)
2022-03-19 17:58:21 +08:00
for k := range j.Var().Map() {
2019-06-19 09:06:52 +08:00
m := make(map[string]string)
for mapKey, mapValue := range j.Get(k).MapStrStr() {
m[mapKey] = mapValue
2019-06-19 09:06:52 +08:00
}
sfm[k] = m
}
}
return sfm
}
2020-05-01 03:31:04 +08:00
// restartWebServers restarts all servers.
func restartWebServers(ctx context.Context, signal os.Signal, newExeFilePath string) error {
2020-12-15 20:16:17 +08:00
serverProcessStatus.Set(adminActionRestarting)
2019-06-19 09:06:52 +08:00
if runtime.GOOS == "windows" {
if signal != nil {
2020-05-01 03:31:04 +08:00
// Controlled by signal.
2021-09-27 21:27:24 +08:00
forceCloseWebServers(ctx)
if err := forkRestartProcess(ctx, newExeFilePath); err != nil {
intlog.Errorf(ctx, `%+v`, err)
2021-09-27 21:27:24 +08:00
}
return nil
2019-06-19 09:06:52 +08:00
}
// Controlled by web page.
// It should ensure the response wrote to client and then close all servers gracefully.
gtimer.SetTimeout(ctx, time.Second, func(ctx context.Context) {
forceCloseWebServers(ctx)
if err := forkRestartProcess(ctx, newExeFilePath); err != nil {
intlog.Errorf(ctx, `%+v`, err)
}
})
return nil
}
if err := forkReloadProcess(ctx, newExeFilePath); err != nil {
glog.Printf(ctx, "%d: server restarts failed", gproc.Pid())
serverProcessStatus.Set(adminActionNone)
return err
2019-06-19 09:06:52 +08:00
} else {
if signal != nil {
glog.Printf(ctx, "%d: server restarting by signal: %s", gproc.Pid(), signal)
2019-06-19 09:06:52 +08:00
} else {
glog.Printf(ctx, "%d: server restarting by web admin", gproc.Pid())
2019-06-19 09:06:52 +08:00
}
}
return nil
}
// shutdownWebServersGracefully gracefully shuts down all servers.
func shutdownWebServersGracefully(ctx context.Context, signal os.Signal) {
serverProcessStatus.Set(adminActionShuttingDown)
if signal != nil {
glog.Printf(
ctx,
"%d: server gracefully shutting down by signal: %s",
gproc.Pid(), signal.String(),
)
} else {
glog.Printf(ctx, "pid[%d]: server gracefully shutting down by api", gproc.Pid())
}
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
serverMapping.RLockFunc(func(m map[string]any) {
2019-06-19 09:06:52 +08:00
for _, v := range m {
server := v.(*Server)
server.doServiceDeregister()
for _, s := range server.servers {
s.Shutdown(ctx)
2019-06-19 09:06:52 +08:00
}
}
})
}
2020-05-01 03:31:04 +08:00
// forceCloseWebServers forced shuts down all servers.
2021-09-27 21:27:24 +08:00
func forceCloseWebServers(ctx context.Context) {
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
serverMapping.RLockFunc(func(m map[string]any) {
2019-06-19 09:06:52 +08:00
for _, v := range m {
for _, s := range v.(*Server).servers {
s.Close(ctx)
2019-06-19 09:06:52 +08:00
}
}
})
}
// handleProcessMessage receives and handles the message from processes,
// which are commonly used for graceful reloading feature.
func handleProcessMessage() {
2021-09-27 21:27:24 +08:00
var (
ctx = context.TODO()
)
2019-06-19 09:06:52 +08:00
for {
2020-12-15 20:16:17 +08:00
if msg := gproc.Receive(adminGProcCommGroup); msg != nil {
2019-06-19 09:06:52 +08:00
if bytes.EqualFold(msg.Data, []byte("exit")) {
2021-09-27 21:27:24 +08:00
intlog.Printf(ctx, "%d: process message: exit", gproc.Pid())
shutdownWebServersGracefully(ctx, nil)
allShutdownChan <- struct{}{}
2021-09-27 21:27:24 +08:00
intlog.Printf(ctx, "%d: process message: exit done", gproc.Pid())
2019-06-19 09:06:52 +08:00
return
}
}
}
}