Skip to content

Commit ccad01d

Browse files
authored
feat: support StopOldInstance() to kill old process on startup (#96)
1 parent 2b8f74e commit ccad01d

File tree

2 files changed

+106
-1
lines changed

2 files changed

+106
-1
lines changed

main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package main
1616

1717
import (
18+
"fmt"
19+
1820
"github.com/beego/beego"
1921
"github.com/beego/beego/plugins/cors"
2022
_ "github.com/beego/beego/session/redis"
@@ -25,6 +27,7 @@ import (
2527
"github.com/casbin/caswaf/routers"
2628
"github.com/casbin/caswaf/run"
2729
"github.com/casbin/caswaf/service"
30+
"github.com/casbin/caswaf/util"
2831
)
2932

3033
func main() {
@@ -67,5 +70,12 @@ func main() {
6770

6871
service.Start()
6972

70-
beego.Run()
73+
port := beego.AppConfig.DefaultInt("httpport", 17000)
74+
75+
err := util.StopOldInstance(port)
76+
if err != nil {
77+
panic(err)
78+
}
79+
80+
beego.Run(fmt.Sprintf(":%v", port))
7181
}

util/process.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2023 The casbin Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package util
16+
17+
import (
18+
"fmt"
19+
"os"
20+
"os/exec"
21+
"runtime"
22+
"strconv"
23+
"strings"
24+
)
25+
26+
func getPidByPort(port int) (int, error) {
27+
var cmd *exec.Cmd
28+
switch runtime.GOOS {
29+
case "windows":
30+
cmd = exec.Command("cmd", "/c", "netstat -ano | findstr :"+strconv.Itoa(port))
31+
case "darwin", "linux":
32+
cmd = exec.Command("lsof", "-t", "-i", ":"+strconv.Itoa(port))
33+
default:
34+
return 0, fmt.Errorf("unsupported OS: %s", runtime.GOOS)
35+
}
36+
37+
output, err := cmd.Output()
38+
if err != nil {
39+
if exitErr, ok := err.(*exec.ExitError); ok {
40+
if exitErr.ExitCode() == 1 {
41+
return 0, nil
42+
}
43+
}
44+
return 0, err
45+
}
46+
47+
lines := strings.Split(string(output), "\n")
48+
for _, line := range lines {
49+
fields := strings.Fields(line)
50+
if len(fields) > 0 {
51+
if runtime.GOOS == "windows" {
52+
if len(fields) >= 2 && fields[1] == "0.0.0.0:"+strconv.Itoa(port) {
53+
pid, err := strconv.Atoi(fields[len(fields)-1])
54+
if err != nil {
55+
return 0, err
56+
}
57+
58+
return pid, nil
59+
}
60+
} else {
61+
pid, err := strconv.Atoi(fields[0])
62+
if err != nil {
63+
return 0, err
64+
}
65+
66+
return pid, nil
67+
}
68+
}
69+
}
70+
71+
return 0, nil
72+
}
73+
74+
func StopOldInstance(port int) error {
75+
pid, err := getPidByPort(port)
76+
if err != nil {
77+
return err
78+
}
79+
if pid == 0 {
80+
return nil
81+
}
82+
83+
process, err := os.FindProcess(pid)
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = process.Kill()
89+
if err != nil {
90+
return err
91+
}
92+
93+
fmt.Printf("The old instance with pid: %d has been stopped\n", pid)
94+
return nil
95+
}

0 commit comments

Comments
 (0)