Files
gf/net/ghttp/ghttp_server_admin.go

116 lines
3.0 KiB
Go
Raw Permalink Normal View History

2021-01-17 21:46:25 +08:00
// 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 (
2021-09-27 21:27:24 +08:00
"context"
2019-06-19 09:06:52 +08:00
"strings"
"time"
2019-07-29 21:01:19 +08:00
2021-11-13 23:23:55 +08:00
"github.com/gogf/gf/v2/os/gfile"
2021-10-11 21:41:56 +08:00
"github.com/gogf/gf/v2/os/gproc"
"github.com/gogf/gf/v2/os/gtimer"
"github.com/gogf/gf/v2/os/gview"
)
2020-05-01 03:31:04 +08:00
// utilAdmin is the controller for administration.
type utilAdmin struct{}
// Index shows the administration page.
func (p *utilAdmin) Index(r *Request) {
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
data := map[string]any{
"pid": gproc.Pid(),
"path": gfile.SelfPath(),
"uri": strings.TrimRight(r.URL.Path, "/"),
2019-06-19 09:06:52 +08:00
}
buffer, _ := gview.ParseContent(r.Context(), `
<html>
<head>
<title>GoFrame Web Server Admin</title>
</head>
<body>
<p>Pid: {{.pid}}</p>
<p>File Path: {{.path}}</p>
<p>
<a href="{{$.uri}}/restart">Restart</a>
please make sure it is running using standalone binary not from IDE or "go run"
</p>
<p>
<a href="{{$.uri}}/shutdown">Shutdown</a>
graceful shutdown the server
</p>
</body>
</html>
`, data)
2019-06-19 09:06:52 +08:00
r.Response.Write(buffer)
}
// Restart restarts all the servers in the process.
func (p *utilAdmin) Restart(r *Request) {
2021-09-27 21:27:24 +08:00
var (
ctx = r.Context()
err error
)
// Custom start binary path when this process exits.
2021-09-27 21:27:24 +08:00
path := r.GetQuery("newExeFilePath").String()
2019-06-19 09:06:52 +08:00
if path == "" {
fix: guard os.Args access for wasm which panics when building (#4762) This pull request improves the reliability and safety of server restart and reload operations by ensuring the correct retrieval of the current executable path and process arguments. It replaces direct usage of `os.Args[0]` with a more robust approach using `gfile.SelfPath()`, and adds error handling for cases where the executable path cannot be determined. Additionally, it introduces a helper function to safely obtain process arguments, and removes an unnecessary import. **Executable Path Handling and Error Checking:** - Replaced usage of `os.Args[0]` with `gfile.SelfPath()` throughout the server admin and process management code to reliably determine the current executable path; added checks and error responses when the path cannot be determined. [[1]](diffhunk://#diff-0d174b149c56c4aa7ffeba2be94d16dc1b8000933f1f2a2e6bf011acdad3272fL122-R134) [[2]](diffhunk://#diff-0d174b149c56c4aa7ffeba2be94d16dc1b8000933f1f2a2e6bf011acdad3272fL168-R184) [[3]](diffhunk://#diff-3b4265be7ef0335b832dacfc2fc7ddc0f9dfae5b81340ff57d2b6a526c60d9e1L62-R65) - Added early returns in initialization functions if `os.Args` is empty, preventing potential panics or misbehavior when the argument list is missing. [[1]](diffhunk://#diff-0aa99f033274ea60b9c466ae4fc98d0816ec13781d8ec787fb3ef106a49a79ecR35-R37) [[2]](diffhunk://#diff-5782fa47aa858b8e8358fd50353b050ee30418b7844b36e313e9c6d01188c092R47-R49) **Process Argument Handling:** - Introduced the `getCurrentProcessArgs()` helper function to safely return process arguments (excluding the program name), ensuring correct behavior even if no arguments are provided. Updated process creation calls to use this helper. **Code Cleanup:** - Removed an unused import of the `os` package from `ghttp_server_admin.go`. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-22 20:44:57 +08:00
path = gfile.SelfPath()
}
if path == "" {
r.Response.WriteExit("cannot determine current executable path")
return
2019-06-19 09:06:52 +08:00
}
if err = RestartAllServer(ctx, path); err == nil {
r.Response.WriteExit("server restarted")
2019-06-19 09:06:52 +08:00
} else {
r.Response.WriteExit(err.Error())
2019-06-19 09:06:52 +08:00
}
}
// Shutdown shuts down all the servers.
func (p *utilAdmin) Shutdown(r *Request) {
gtimer.SetTimeout(r.Context(), time.Second, func(ctx context.Context) {
// It shuts down the server after 1 second, which is not triggered by system signal,
// to ensure the response successfully to the client.
_ = r.Server.Shutdown()
})
r.Response.WriteExit("server shutdown")
}
// EnableAdmin enables the administration feature for the process.
// The optional parameter `pattern` specifies the URI for the administration page.
2019-06-19 09:06:52 +08:00
func (s *Server) EnableAdmin(pattern ...string) {
p := "/debug/admin"
if len(pattern) > 0 {
p = pattern[0]
}
s.BindObject(p, &utilAdmin{})
}
// Shutdown shuts the current server.
func (s *Server) Shutdown() error {
var ctx = context.TODO()
// Remove plugins.
if len(s.plugins) > 0 {
for _, p := range s.plugins {
s.Logger().Printf(ctx, `remove plugin: %s`, p.Name())
if err := p.Remove(); err != nil {
s.Logger().Errorf(ctx, "%+v", err)
}
}
}
s.doServiceDeregister()
// Only shut down current servers.
// It may have multiple underlying http servers.
for _, v := range s.servers {
v.Shutdown(ctx)
}
s.Logger().Infof(ctx, "pid[%d]: all servers shutdown", gproc.Pid())
2019-06-19 09:06:52 +08:00
return nil
}