github.com/gogf/gf/v2@v2.7.4/net/ghttp/ghttp_server_admin.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package ghttp
     8  
     9  import (
    10  	"context"
    11  	"os"
    12  	"strings"
    13  	"time"
    14  
    15  	"github.com/gogf/gf/v2/os/gfile"
    16  	"github.com/gogf/gf/v2/os/gproc"
    17  	"github.com/gogf/gf/v2/os/gtimer"
    18  	"github.com/gogf/gf/v2/os/gview"
    19  )
    20  
    21  // utilAdmin is the controller for administration.
    22  type utilAdmin struct{}
    23  
    24  // Index shows the administration page.
    25  func (p *utilAdmin) Index(r *Request) {
    26  	data := map[string]interface{}{
    27  		"pid":  gproc.Pid(),
    28  		"path": gfile.SelfPath(),
    29  		"uri":  strings.TrimRight(r.URL.Path, "/"),
    30  	}
    31  	buffer, _ := gview.ParseContent(r.Context(), `
    32              <html>
    33              <head>
    34                  <title>GoFrame Web Server Admin</title>
    35              </head>
    36              <body>
    37                  <p>Pid: {{.pid}}</p>
    38                  <p>File Path: {{.path}}</p>
    39                  <p>
    40  <a href="{{$.uri}}/restart">Restart</a>
    41  please make sure it is running using standalone binary not from IDE or "go run"
    42  </p>
    43                  <p>
    44  <a href="{{$.uri}}/shutdown">Shutdown</a>
    45  graceful shutdown the server
    46  </p>
    47              </body>
    48              </html>
    49      `, data)
    50  	r.Response.Write(buffer)
    51  }
    52  
    53  // Restart restarts all the servers in the process.
    54  func (p *utilAdmin) Restart(r *Request) {
    55  	var (
    56  		ctx = r.Context()
    57  		err error
    58  	)
    59  	// Custom start binary path when this process exits.
    60  	path := r.GetQuery("newExeFilePath").String()
    61  	if path == "" {
    62  		path = os.Args[0]
    63  	}
    64  	if err = RestartAllServer(ctx, path); err == nil {
    65  		r.Response.WriteExit("server restarted")
    66  	} else {
    67  		r.Response.WriteExit(err.Error())
    68  	}
    69  }
    70  
    71  // Shutdown shuts down all the servers.
    72  func (p *utilAdmin) Shutdown(r *Request) {
    73  	gtimer.SetTimeout(r.Context(), time.Second, func(ctx context.Context) {
    74  		// It shuts down the server after 1 second, which is not triggered by system signal,
    75  		// to ensure the response successfully to the client.
    76  		_ = r.Server.Shutdown()
    77  	})
    78  	r.Response.WriteExit("server shutdown")
    79  }
    80  
    81  // EnableAdmin enables the administration feature for the process.
    82  // The optional parameter `pattern` specifies the URI for the administration page.
    83  func (s *Server) EnableAdmin(pattern ...string) {
    84  	p := "/debug/admin"
    85  	if len(pattern) > 0 {
    86  		p = pattern[0]
    87  	}
    88  	s.BindObject(p, &utilAdmin{})
    89  }
    90  
    91  // Shutdown shuts down current server.
    92  func (s *Server) Shutdown() error {
    93  	var ctx = context.TODO()
    94  	s.doServiceDeregister()
    95  	// Only shut down current servers.
    96  	// It may have multiple underlying http servers.
    97  	for _, v := range s.servers {
    98  		v.shutdown(ctx)
    99  	}
   100  	return nil
   101  }