mirror of
				https://github.com/TeaOSLab/EdgeNode.git
				synced 2025-11-04 16:00:25 +08:00 
			
		
		
		
	使用Sock管理进程启停
This commit is contained in:
		@@ -5,15 +5,12 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeNode/internal/apps"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/apps"
 | 
				
			||||||
	teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
						teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/nodes"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/nodes"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
						_ "github.com/iwind/TeaGo/bootstrap"
 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
						"github.com/iwind/gosock/pkg/gosock"
 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	_ "net/http/pprof"
 | 
						_ "net/http/pprof"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
@@ -40,25 +37,13 @@ func main() {
 | 
				
			|||||||
		fmt.Println("done")
 | 
							fmt.Println("done")
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	app.On("quit", func() {
 | 
						app.On("quit", func() {
 | 
				
			||||||
		pidFile := Tea.Root + "/bin/pid"
 | 
							var sock = gosock.NewTmpSock(teaconst.ProcessName)
 | 
				
			||||||
		data, err := ioutil.ReadFile(pidFile)
 | 
							_, err := sock.Send(&gosock.Command{Code: "quit"})
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println("[ERROR]quit failed: " + err.Error())
 | 
								fmt.Println("[ERROR]quit failed: " + err.Error())
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		pid := types.Int(string(data))
 | 
							fmt.Println("done")
 | 
				
			||||||
		if pid == 0 {
 | 
					 | 
				
			||||||
			fmt.Println("[ERROR]quit failed: pid=0")
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		process, err := os.FindProcess(pid)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if process != nil {
 | 
					 | 
				
			||||||
			_ = process.Signal(syscall.SIGQUIT)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	app.On("pprof", func() {
 | 
						app.On("pprof", func() {
 | 
				
			||||||
		// TODO 自己指定端口
 | 
							// TODO 自己指定端口
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							@@ -14,6 +14,7 @@ require (
 | 
				
			|||||||
	github.com/golang/protobuf v1.5.2
 | 
						github.com/golang/protobuf v1.5.2
 | 
				
			||||||
	github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060
 | 
						github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060
 | 
				
			||||||
	github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11
 | 
						github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11
 | 
				
			||||||
 | 
						github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3
 | 
				
			||||||
	github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
						github.com/lionsoul2014/ip2region v2.2.0-release+incompatible
 | 
				
			||||||
	github.com/mattn/go-sqlite3 v2.0.3+incompatible
 | 
						github.com/mattn/go-sqlite3 v2.0.3+incompatible
 | 
				
			||||||
	github.com/mssola/user_agent v0.5.2
 | 
						github.com/mssola/user_agent v0.5.2
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.sum
									
									
									
									
									
								
							@@ -66,8 +66,9 @@ github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060 h1:qdLtK4PDXxk2vMKkTWl
 | 
				
			|||||||
github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
					github.com/iwind/TeaGo v0.0.0-20210628135026-38575a4ab060/go.mod h1:KU4mS7QNiZ7QWEuDBk1zw0/Q2LrAPZv3tycEFBsuUwc=
 | 
				
			||||||
github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11 h1:DaQjoWZhLNxjhIXedVg4/vFEtHkZhK4IjIwsWdyzBLg=
 | 
					github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11 h1:DaQjoWZhLNxjhIXedVg4/vFEtHkZhK4IjIwsWdyzBLg=
 | 
				
			||||||
github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11/go.mod h1:JtbX20untAjUVjZs1ZBtq80f5rJWvwtQNRL6EnuYRnY=
 | 
					github.com/iwind/gofcgi v0.0.0-20210528023741-a92711d45f11/go.mod h1:JtbX20untAjUVjZs1ZBtq80f5rJWvwtQNRL6EnuYRnY=
 | 
				
			||||||
 | 
					github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
 | 
				
			||||||
 | 
					github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
 | 
				
			||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
					github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
				
			||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 | 
					 | 
				
			||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
					github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
				
			||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
					github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
				
			||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
					github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 | 
				
			||||||
@@ -77,9 +78,7 @@ github.com/lionsoul2014/ip2region v2.2.0-release+incompatible/go.mod h1:+ZBN7PBo
 | 
				
			|||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 | 
					github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 | 
				
			||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 | 
					github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
					github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
				
			||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 | 
					 | 
				
			||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					 | 
				
			||||||
github.com/mssola/user_agent v0.5.2 h1:CZkTUahjL1+OcZ5zv3kZr8QiJ8jy2H08vZIEkBeRbxo=
 | 
					github.com/mssola/user_agent v0.5.2 h1:CZkTUahjL1+OcZ5zv3kZr8QiJ8jy2H08vZIEkBeRbxo=
 | 
				
			||||||
github.com/mssola/user_agent v0.5.2/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
 | 
					github.com/mssola/user_agent v0.5.2/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
 | 
				
			||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,11 @@ package apps
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/types"
 | 
				
			||||||
 | 
						"github.com/iwind/gosock/pkg/gosock"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
@@ -11,7 +14,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// App命令帮助
 | 
					// AppCmd App命令帮助
 | 
				
			||||||
type AppCmd struct {
 | 
					type AppCmd struct {
 | 
				
			||||||
	product       string
 | 
						product       string
 | 
				
			||||||
	version       string
 | 
						version       string
 | 
				
			||||||
@@ -20,10 +23,14 @@ type AppCmd struct {
 | 
				
			|||||||
	appendStrings []string
 | 
						appendStrings []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	directives []*Directive
 | 
						directives []*Directive
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sock *gosock.Sock
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewAppCmd() *AppCmd {
 | 
					func NewAppCmd() *AppCmd {
 | 
				
			||||||
	return &AppCmd{}
 | 
						return &AppCmd{
 | 
				
			||||||
 | 
							sock: gosock.NewTmpSock(teaconst.ProcessName),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CommandHelpOption struct {
 | 
					type CommandHelpOption struct {
 | 
				
			||||||
@@ -31,25 +38,25 @@ type CommandHelpOption struct {
 | 
				
			|||||||
	Description string
 | 
						Description string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 产品
 | 
					// Product 产品
 | 
				
			||||||
func (this *AppCmd) Product(product string) *AppCmd {
 | 
					func (this *AppCmd) Product(product string) *AppCmd {
 | 
				
			||||||
	this.product = product
 | 
						this.product = product
 | 
				
			||||||
	return this
 | 
						return this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 版本
 | 
					// Version 版本
 | 
				
			||||||
func (this *AppCmd) Version(version string) *AppCmd {
 | 
					func (this *AppCmd) Version(version string) *AppCmd {
 | 
				
			||||||
	this.version = version
 | 
						this.version = version
 | 
				
			||||||
	return this
 | 
						return this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 使用方法
 | 
					// Usage 使用方法
 | 
				
			||||||
func (this *AppCmd) Usage(usage string) *AppCmd {
 | 
					func (this *AppCmd) Usage(usage string) *AppCmd {
 | 
				
			||||||
	this.usage = usage
 | 
						this.usage = usage
 | 
				
			||||||
	return this
 | 
						return this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 选项
 | 
					// Option 选项
 | 
				
			||||||
func (this *AppCmd) Option(code string, description string) *AppCmd {
 | 
					func (this *AppCmd) Option(code string, description string) *AppCmd {
 | 
				
			||||||
	this.options = append(this.options, &CommandHelpOption{
 | 
						this.options = append(this.options, &CommandHelpOption{
 | 
				
			||||||
		Code:        code,
 | 
							Code:        code,
 | 
				
			||||||
@@ -58,13 +65,13 @@ func (this *AppCmd) Option(code string, description string) *AppCmd {
 | 
				
			|||||||
	return this
 | 
						return this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 附加内容
 | 
					// Append 附加内容
 | 
				
			||||||
func (this *AppCmd) Append(appendString string) *AppCmd {
 | 
					func (this *AppCmd) Append(appendString string) *AppCmd {
 | 
				
			||||||
	this.appendStrings = append(this.appendStrings, appendString)
 | 
						this.appendStrings = append(this.appendStrings, appendString)
 | 
				
			||||||
	return this
 | 
						return this
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 打印
 | 
					// Print 打印
 | 
				
			||||||
func (this *AppCmd) Print() {
 | 
					func (this *AppCmd) Print() {
 | 
				
			||||||
	fmt.Println(this.product + " v" + this.version)
 | 
						fmt.Println(this.product + " v" + this.version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -103,7 +110,7 @@ func (this *AppCmd) Print() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 添加指令
 | 
					// On 添加指令
 | 
				
			||||||
func (this *AppCmd) On(arg string, callback func()) {
 | 
					func (this *AppCmd) On(arg string, callback func()) {
 | 
				
			||||||
	this.directives = append(this.directives, &Directive{
 | 
						this.directives = append(this.directives, &Directive{
 | 
				
			||||||
		Arg:      arg,
 | 
							Arg:      arg,
 | 
				
			||||||
@@ -111,7 +118,7 @@ func (this *AppCmd) On(arg string, callback func()) {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 运行
 | 
					// Run 运行
 | 
				
			||||||
func (this *AppCmd) Run(main func()) {
 | 
					func (this *AppCmd) Run(main func()) {
 | 
				
			||||||
	// 获取参数
 | 
						// 获取参数
 | 
				
			||||||
	args := os.Args[1:]
 | 
						args := os.Args[1:]
 | 
				
			||||||
@@ -161,7 +168,7 @@ func (this *AppCmd) Run(main func()) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 版本号
 | 
					// 版本号
 | 
				
			||||||
func (this *AppCmd) runVersion() {
 | 
					func (this *AppCmd) runVersion() {
 | 
				
			||||||
	fmt.Println(this.product+" v"+this.version, "(build: "+runtime.Version(), runtime.GOOS, runtime.GOARCH+")")
 | 
						fmt.Println(this.product+" v"+this.version, "(build: "+runtime.Version(), runtime.GOOS, runtime.GOARCH, teaconst.Tag+")")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 帮助
 | 
					// 帮助
 | 
				
			||||||
@@ -171,9 +178,9 @@ func (this *AppCmd) runHelp() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 启动
 | 
					// 启动
 | 
				
			||||||
func (this *AppCmd) runStart() {
 | 
					func (this *AppCmd) runStart() {
 | 
				
			||||||
	proc := this.checkPid()
 | 
						var pid = this.getPID()
 | 
				
			||||||
	if proc != nil {
 | 
						if pid > 0 {
 | 
				
			||||||
		fmt.Println(this.product+" already started, pid:", proc.Pid)
 | 
							fmt.Println(this.product+" already started, pid:", pid)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -189,18 +196,15 @@ func (this *AppCmd) runStart() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 停止
 | 
					// 停止
 | 
				
			||||||
func (this *AppCmd) runStop() {
 | 
					func (this *AppCmd) runStop() {
 | 
				
			||||||
	proc := this.checkPid()
 | 
						var pid = this.getPID()
 | 
				
			||||||
	if proc == nil {
 | 
						if pid == 0 {
 | 
				
			||||||
		fmt.Println(this.product + " not started yet")
 | 
							fmt.Println(this.product + " not started yet")
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 停止进程
 | 
						_, _ = this.sock.Send(&gosock.Command{Code: "stop"})
 | 
				
			||||||
	_ = proc.Kill()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 在Windows上经常不能及时释放资源
 | 
						fmt.Println(this.product+" stopped ok, pid:", types.String(pid))
 | 
				
			||||||
	_ = DeletePid(Tea.Root + "/bin/pid")
 | 
					 | 
				
			||||||
	fmt.Println(this.product+" stopped ok, pid:", proc.Pid)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 重启
 | 
					// 重启
 | 
				
			||||||
@@ -212,15 +216,24 @@ func (this *AppCmd) runRestart() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 状态
 | 
					// 状态
 | 
				
			||||||
func (this *AppCmd) runStatus() {
 | 
					func (this *AppCmd) runStatus() {
 | 
				
			||||||
	proc := this.checkPid()
 | 
						var pid = this.getPID()
 | 
				
			||||||
	if proc == nil {
 | 
						if pid == 0 {
 | 
				
			||||||
		fmt.Println(this.product + " not started yet")
 | 
							fmt.Println(this.product + " not started yet")
 | 
				
			||||||
	} else {
 | 
							return
 | 
				
			||||||
		fmt.Println(this.product + " is running, pid: " + fmt.Sprintf("%d", proc.Pid))
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Println(this.product + " is running, pid: " + types.String(pid))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 检查PID
 | 
					// 获取当前的PID
 | 
				
			||||||
func (this *AppCmd) checkPid() *os.Process {
 | 
					func (this *AppCmd) getPID() int {
 | 
				
			||||||
	return CheckPid(Tea.Root + "/bin/pid")
 | 
						if !this.sock.IsListening() {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reply, err := this.sock.Send(&gosock.Command{Code: "pid"})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return maps.NewMap(reply.Params).GetInt("pid")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
// +build windows
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package apps
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// lock file
 | 
					 | 
				
			||||||
func LockFile(fp *os.File) error {
 | 
					 | 
				
			||||||
	return errors.New("not implemented on windows")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func UnlockFile(fp *os.File) error {
 | 
					 | 
				
			||||||
	return errors.New("not implemented on windows")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,119 +0,0 @@
 | 
				
			|||||||
package apps
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/events"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var pidFileList = []*os.File{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 检查Pid
 | 
					 | 
				
			||||||
func CheckPid(path string) *os.Process {
 | 
					 | 
				
			||||||
	// windows上打开的文件是不能删除的
 | 
					 | 
				
			||||||
	if runtime.GOOS == "windows" {
 | 
					 | 
				
			||||||
		if os.Remove(path) == nil {
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	file, err := os.Open(path)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		_ = file.Close()
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 是否能取得Lock
 | 
					 | 
				
			||||||
	err = LockFile(file)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		_ = UnlockFile(file)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pidBytes, err := ioutil.ReadAll(file)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pid := types.Int(string(pidBytes))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if pid <= 0 {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	proc, _ := os.FindProcess(pid)
 | 
					 | 
				
			||||||
	return proc
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 写入Pid
 | 
					 | 
				
			||||||
func WritePid() error {
 | 
					 | 
				
			||||||
	path := Tea.Root + "/bin/pid"
 | 
					 | 
				
			||||||
	fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	events.On(events.EventQuit, func() {
 | 
					 | 
				
			||||||
		_ = fp.Close()
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if runtime.GOOS != "windows" {
 | 
					 | 
				
			||||||
		err = LockFile(fp)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pidFileList = append(pidFileList, fp) // hold the file pointers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err = fp.WriteString(fmt.Sprintf("%d", os.Getpid()))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 写入Ppid
 | 
					 | 
				
			||||||
func WritePpid(path string) error {
 | 
					 | 
				
			||||||
	fp, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_RDONLY, 0666)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if runtime.GOOS != "windows" {
 | 
					 | 
				
			||||||
		err = LockFile(fp)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	pidFileList = append(pidFileList, fp) // hold the file pointers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_, err = fp.WriteString(fmt.Sprintf("%d", os.Getppid()))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 删除Pid
 | 
					 | 
				
			||||||
func DeletePid(path string) error {
 | 
					 | 
				
			||||||
	_, err := os.Stat(path)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if !os.IsNotExist(err) {
 | 
					 | 
				
			||||||
			return nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, fp := range pidFileList {
 | 
					 | 
				
			||||||
		_ = UnlockFile(fp)
 | 
					 | 
				
			||||||
		_ = fp.Close()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return os.Remove(path)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										8
									
								
								internal/const/build.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/const/build.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					// +build community
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package teaconst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const BuildCommunity = true
 | 
				
			||||||
 | 
					const BuildPlus = false
 | 
				
			||||||
 | 
					const Tag = "community"
 | 
				
			||||||
							
								
								
									
										8
									
								
								internal/const/build_plus.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								internal/const/build_plus.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
				
			||||||
 | 
					// +build plus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package teaconst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const BuildCommunity = false
 | 
				
			||||||
 | 
					const BuildPlus = true
 | 
				
			||||||
 | 
					const Tag = "plus"
 | 
				
			||||||
@@ -6,7 +6,6 @@ import (
 | 
				
			|||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/apps"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/caches"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/caches"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
						"github.com/TeaOSLab/EdgeNode/internal/configs"
 | 
				
			||||||
	teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
						teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
 | 
				
			||||||
@@ -21,14 +20,14 @@ import (
 | 
				
			|||||||
	"github.com/iwind/TeaGo/Tea"
 | 
						"github.com/iwind/TeaGo/Tea"
 | 
				
			||||||
	"github.com/iwind/TeaGo/lists"
 | 
						"github.com/iwind/TeaGo/lists"
 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
						"github.com/iwind/TeaGo/logs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"github.com/iwind/gosock/pkg/gosock"
 | 
				
			||||||
	"io/ioutil"
 | 
						"io/ioutil"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"os/signal"
 | 
					 | 
				
			||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
	"syscall"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,6 +39,7 @@ var DaemonPid = 0
 | 
				
			|||||||
// Node 节点
 | 
					// Node 节点
 | 
				
			||||||
type Node struct {
 | 
					type Node struct {
 | 
				
			||||||
	isLoaded bool
 | 
						isLoaded bool
 | 
				
			||||||
 | 
						sock     *gosock.Sock
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewNode() *Node {
 | 
					func NewNode() *Node {
 | 
				
			||||||
@@ -73,9 +73,6 @@ func (this *Node) Start() {
 | 
				
			|||||||
	// 启动事件
 | 
						// 启动事件
 | 
				
			||||||
	events.Notify(events.EventStart)
 | 
						events.Notify(events.EventStart)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 处理信号
 | 
					 | 
				
			||||||
	this.listenSignals()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 本地Sock
 | 
						// 本地Sock
 | 
				
			||||||
	err := this.listenSock()
 | 
						err := this.listenSock()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -152,13 +149,6 @@ func (this *Node) Start() {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 写入PID
 | 
					 | 
				
			||||||
	err = apps.WritePid()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		remotelogs.Error("NODE", "write pid failed: "+err.Error())
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// hold住进程
 | 
						// hold住进程
 | 
				
			||||||
	select {}
 | 
						select {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -229,32 +219,6 @@ func (this *Node) InstallSystemService() error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 处理信号
 | 
					 | 
				
			||||||
func (this *Node) listenSignals() {
 | 
					 | 
				
			||||||
	signals := make(chan os.Signal)
 | 
					 | 
				
			||||||
	signal.Notify(signals, syscall.SIGQUIT)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		for s := range signals {
 | 
					 | 
				
			||||||
			switch s {
 | 
					 | 
				
			||||||
			case syscall.SIGQUIT:
 | 
					 | 
				
			||||||
				events.Notify(events.EventQuit)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// 监控连接数,如果连接数为0,则退出进程
 | 
					 | 
				
			||||||
				go func() {
 | 
					 | 
				
			||||||
					for {
 | 
					 | 
				
			||||||
						countActiveConnections := sharedListenerManager.TotalActiveConnections()
 | 
					 | 
				
			||||||
						if countActiveConnections <= 0 {
 | 
					 | 
				
			||||||
							os.Exit(0)
 | 
					 | 
				
			||||||
							return
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						time.Sleep(1 * time.Second)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 循环
 | 
					// 循环
 | 
				
			||||||
func (this *Node) loop() error {
 | 
					func (this *Node) loop() error {
 | 
				
			||||||
	// 检查api.yaml是否存在
 | 
						// 检查api.yaml是否存在
 | 
				
			||||||
@@ -493,37 +457,65 @@ func (this *Node) checkClusterConfig() error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// 监听本地sock
 | 
					// 监听本地sock
 | 
				
			||||||
func (this *Node) listenSock() error {
 | 
					func (this *Node) listenSock() error {
 | 
				
			||||||
	path := os.TempDir() + "/edge-node.sock"
 | 
						this.sock = gosock.NewTmpSock(teaconst.ProcessName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 检查是否已经存在
 | 
						// 检查是否在运行
 | 
				
			||||||
	_, err := os.Stat(path)
 | 
						if this.sock.IsListening() {
 | 
				
			||||||
	if err == nil {
 | 
							reply, err := this.sock.Send(&gosock.Command{Code: "pid"})
 | 
				
			||||||
		conn, err := net.Dial("unix", path)
 | 
							if err == nil {
 | 
				
			||||||
		if err != nil {
 | 
								return errors.New("error: the process is already running, pid: " + maps.NewMap(reply.Params).GetString("pid"))
 | 
				
			||||||
			_ = os.Remove(path)
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			_ = conn.Close()
 | 
								return errors.New("error: the process is already running")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 新的监听任务
 | 
						// 启动监听
 | 
				
			||||||
	listener, err := net.Listen("unix", path)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	events.On(events.EventQuit, func() {
 | 
					 | 
				
			||||||
		remotelogs.Println("NODE", "quit unix sock")
 | 
					 | 
				
			||||||
		_ = listener.Close()
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	go func() {
 | 
						go func() {
 | 
				
			||||||
		for {
 | 
							this.sock.OnCommand(func(cmd *gosock.Command) {
 | 
				
			||||||
			_, err := listener.Accept()
 | 
								switch cmd.Code {
 | 
				
			||||||
			if err != nil {
 | 
								case "pid":
 | 
				
			||||||
				return
 | 
									_ = cmd.Reply(&gosock.Command{
 | 
				
			||||||
 | 
										Code: "pid",
 | 
				
			||||||
 | 
										Params: map[string]interface{}{
 | 
				
			||||||
 | 
											"pid": os.Getpid(),
 | 
				
			||||||
 | 
										},
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								case "stop":
 | 
				
			||||||
 | 
									_ = cmd.ReplyOk()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// 退出主进程
 | 
				
			||||||
 | 
									events.Notify(events.EventQuit)
 | 
				
			||||||
 | 
									os.Exit(0)
 | 
				
			||||||
 | 
								case "quit":
 | 
				
			||||||
 | 
									_ = cmd.ReplyOk()
 | 
				
			||||||
 | 
									_ = this.sock.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									events.Notify(events.EventQuit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// 监控连接数,如果连接数为0,则退出进程
 | 
				
			||||||
 | 
									go func() {
 | 
				
			||||||
 | 
										for {
 | 
				
			||||||
 | 
											countActiveConnections := sharedListenerManager.TotalActiveConnections()
 | 
				
			||||||
 | 
											if countActiveConnections <= 0 {
 | 
				
			||||||
 | 
												os.Exit(0)
 | 
				
			||||||
 | 
												return
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											time.Sleep(1 * time.Second)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err := this.sock.Listen()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logs.Println("NODE", err.Error())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						events.On(events.EventQuit, func() {
 | 
				
			||||||
 | 
							logs.Println("NODE", "quit unix sock")
 | 
				
			||||||
 | 
							_ = this.sock.Close()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user