Skip to content

Commit ed3d587

Browse files
fix: 解决守护进程停止之后状态读取异常的问题 (#2186)
Refs #2167
1 parent 38b462e commit ed3d587

File tree

5 files changed

+63
-94
lines changed

5 files changed

+63
-94
lines changed

backend/app/api/v1/host_tool.go

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -189,21 +189,6 @@ func (b *BaseApi) GetProcess(c *gin.Context) {
189189
helper.SuccessWithData(c, configs)
190190
}
191191

192-
// @Tags Host tool
193-
// @Summary Load Supervisor process status
194-
// @Description 获取 Supervisor 进程状态
195-
// @Success 200 {array} response.ProcessStatus
196-
// @Security ApiKeyAuth
197-
// @Router /host/tool/supervisor/process/load [post]
198-
func (b *BaseApi) LoadProcessStatus(c *gin.Context) {
199-
datas, err := hostToolService.LoadProcessStatus()
200-
if err != nil {
201-
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
202-
return
203-
}
204-
helper.SuccessWithData(c, datas)
205-
}
206-
207192
// @Tags Host tool
208193
// @Summary Get Supervisor process config
209194
// @Description 操作 Supervisor 进程文件

backend/app/service/host_tool.go

Lines changed: 32 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,6 @@ package service
33
import (
44
"bytes"
55
"fmt"
6-
"os/exec"
7-
"os/user"
8-
"path"
9-
"strconv"
10-
"strings"
11-
"sync"
12-
"time"
13-
146
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
157
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
168
"github.com/1Panel-dev/1Panel/backend/buserr"
@@ -22,6 +14,11 @@ import (
2214
"github.com/1Panel-dev/1Panel/backend/utils/systemctl"
2315
"github.com/pkg/errors"
2416
"gopkg.in/ini.v1"
17+
"os/exec"
18+
"os/user"
19+
"path"
20+
"strconv"
21+
"strings"
2522
)
2623

2724
type HostToolService struct{}
@@ -34,7 +31,6 @@ type IHostToolService interface {
3431
GetToolLog(req request.HostToolLogReq) (string, error)
3532
OperateSupervisorProcess(req request.SupervisorProcessConfig) error
3633
GetSupervisorProcessConfig() ([]response.SupervisorProcessConfig, error)
37-
LoadProcessStatus() ([]response.ProcessStatus, error)
3834
OperateSupervisorProcessFile(req request.SupervisorProcessFileReq) (string, error)
3935
}
4036

@@ -377,56 +373,6 @@ func (h *HostToolService) OperateSupervisorProcess(req request.SupervisorProcess
377373
return nil
378374
}
379375

380-
func (h *HostToolService) LoadProcessStatus() ([]response.ProcessStatus, error) {
381-
var res []response.ProcessStatus
382-
statusLines, _ := cmd.Exec("supervisorctl status")
383-
if len(statusLines) == 0 {
384-
return res, nil
385-
}
386-
lines := strings.Split(statusLines, "\n")
387-
for _, line := range lines {
388-
fields := strings.Fields(line)
389-
if len(fields) > 1 {
390-
res = append(res, response.ProcessStatus{Name: fields[0]})
391-
}
392-
}
393-
394-
var wg sync.WaitGroup
395-
wg.Add(len(res))
396-
for i := 0; i < len(res); i++ {
397-
go func(index int) {
398-
for t := 0; t < 3; t++ {
399-
status, err := cmd.ExecWithTimeOut(fmt.Sprintf("supervisorctl status %s", res[index].Name), 2*time.Second)
400-
if err != nil {
401-
time.Sleep(2 * time.Second)
402-
continue
403-
}
404-
fields := strings.Fields(status)
405-
if len(fields) < 5 {
406-
time.Sleep(2 * time.Second)
407-
continue
408-
}
409-
res[index].Name = fields[0]
410-
res[index].Status = fields[1]
411-
if fields[1] != "RUNNING" {
412-
res[index].Msg = strings.Join(fields[2:], " ")
413-
break
414-
}
415-
res[index].PID = strings.TrimSuffix(fields[3], ",")
416-
res[index].Uptime = fields[5]
417-
break
418-
}
419-
if len(res[index].Status) == 0 {
420-
res[index].Status = "FATAL"
421-
res[index].Msg = "Timeout for getting process status"
422-
}
423-
wg.Done()
424-
}(i)
425-
}
426-
wg.Wait()
427-
return res, nil
428-
}
429-
430376
func (h *HostToolService) GetSupervisorProcessConfig() ([]response.SupervisorProcessConfig, error) {
431377
var (
432378
result []response.SupervisorProcessConfig
@@ -463,6 +409,7 @@ func (h *HostToolService) GetSupervisorProcessConfig() ([]response.SupervisorPro
463409
if numprocs, _ := section.GetKey("numprocs"); numprocs != nil {
464410
config.Numprocs = numprocs.Value()
465411
}
412+
_ = getProcessStatus(&config)
466413
result = append(result, config)
467414
}
468415
}
@@ -590,3 +537,29 @@ func getProcessName(name, numprocs string) []string {
590537
}
591538
return processNames
592539
}
540+
541+
func getProcessStatus(config *response.SupervisorProcessConfig) error {
542+
var (
543+
processNames = []string{"status"}
544+
)
545+
processNames = append(processNames, getProcessName(config.Name, config.Numprocs)...)
546+
output, _ := exec.Command("supervisorctl", processNames...).Output()
547+
lines := strings.Split(string(output), "\n")
548+
for _, line := range lines {
549+
fields := strings.Fields(line)
550+
if len(fields) >= 5 {
551+
status := response.ProcessStatus{
552+
Name: fields[0],
553+
Status: fields[1],
554+
}
555+
if fields[1] == "RUNNING" {
556+
status.PID = strings.TrimSuffix(fields[3], ",")
557+
status.Uptime = fields[5]
558+
} else {
559+
status.Msg = strings.Join(fields[2:], " ")
560+
}
561+
config.Status = append(config.Status, status)
562+
}
563+
}
564+
return nil
565+
}

backend/router/ro_host.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
5555
hostRouter.POST("/tool/operate", baseApi.OperateTool)
5656
hostRouter.POST("/tool/config", baseApi.OperateToolConfig)
5757
hostRouter.POST("/tool/log", baseApi.GetToolLog)
58-
hostRouter.POST("/tool/supervisor/process/load", baseApi.LoadProcessStatus)
5958
hostRouter.POST("/tool/supervisor/process", baseApi.OperateProcess)
6059
hostRouter.GET("/tool/supervisor/process", baseApi.GetProcess)
6160
hostRouter.POST("/tool/supervisor/process/file", baseApi.GetProcessFile)

frontend/src/api/modules/host-tool.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const LoadProcessStatus = () => {
3434
};
3535

3636
export const GetSupervisorProcess = () => {
37-
return http.get<HostTool.SupersivorProcess>(`/hosts/tool/supervisor/process`);
37+
return http.get<HostTool.SupersivorProcess[]>(`/hosts/tool/supervisor/process`);
3838
};
3939

4040
export const OperateSupervisorProcessFile = (req: HostTool.ProcessFileReq) => {

frontend/src/views/host/tool/supervisor/index.vue

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ import ConfigSuperVisor from './config/index.vue';
157157
import { computed, onMounted } from 'vue';
158158
import Create from './create/index.vue';
159159
import File from './file/index.vue';
160-
import { GetSupervisorProcess, LoadProcessStatus, OperateSupervisorProcess } from '@/api/modules/host-tool';
160+
import { GetSupervisorProcess, OperateSupervisorProcess } from '@/api/modules/host-tool';
161161
import { GlobalStore } from '@/store';
162162
import i18n from '@/lang';
163163
import { HostTool } from '@/api/interface/host-tool';
@@ -216,34 +216,46 @@ const search = async () => {
216216
return;
217217
}
218218
loading.value = true;
219-
loadStatus();
219+
let needLoadStatus = false;
220220
try {
221221
const res = await GetSupervisorProcess();
222222
data.value = res.data;
223+
for (const process of data.value) {
224+
if (process.status && process.status.length > 0) {
225+
process.hasLoad = true;
226+
} else {
227+
process.hasLoad = false;
228+
needLoadStatus = true;
229+
}
230+
}
231+
if (needLoadStatus) {
232+
setTimeout(loadStatus, 1000);
233+
}
223234
} catch (error) {}
224235
loading.value = false;
225236
};
226237
227238
const loadStatus = async () => {
228-
await LoadProcessStatus()
229-
.then((res) => {
230-
let stats = res.data || [];
231-
for (const process of data.value) {
232-
process.status = [];
233-
for (const item of stats) {
234-
if (process.name === item.name.split(':')[0]) {
235-
process.status.push(item);
239+
let needLoadStatus = false;
240+
try {
241+
const res = await GetSupervisorProcess();
242+
const stats = res.data || [];
243+
for (const process of data.value) {
244+
for (const item of stats) {
245+
if (process.name === item.name) {
246+
if (item.status && item.status.length > 0) {
247+
process.status = item.status;
248+
process.hasLoad = true;
249+
} else {
250+
needLoadStatus = true;
236251
}
237252
}
238-
process.hasLoad = true;
239-
}
240-
})
241-
.catch(() => {
242-
for (const process of data.value) {
243-
process.status = [{ name: '-', status: 'FATAL', msg: i18n.global.t('tool.supervisor.loadStatusErr') }];
244-
process.hasLoad = true;
245253
}
246-
});
254+
}
255+
if (needLoadStatus) {
256+
setTimeout(loadStatus, 2000);
257+
}
258+
} catch (error) {}
247259
};
248260
249261
const mobile = computed(() => {

0 commit comments

Comments
 (0)