Update process.go

- Simplifying the IsRunning method to a single return statement.
- Streamlining the GetResult method to use a loop that reads from the queue until it's empty.
- Using bufio.Scanner in the Start method for reading process output, which simplifies the reading loop.
- Ensuring that the wait group waits for the goroutines to finish after the process ends in the Start method.
This commit is contained in:
BlacKSnowDot0 2023-11-19 17:15:51 -08:00 committed by GitHub
parent ad6d07326a
commit 26174221aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -114,13 +114,7 @@ func newProcess(config *Config) *process {
} }
func (p *process) IsRunning() bool { func (p *process) IsRunning() bool {
if p.cmd == nil || p.cmd.Process == nil { return p.cmd != nil && p.cmd.Process != nil && p.cmd.ProcessState == nil
return false
}
if p.cmd.ProcessState == nil {
return true
}
return false
} }
func (p *process) GetErr() error { func (p *process) GetErr() error {
@ -128,15 +122,14 @@ func (p *process) GetErr() error {
} }
func (p *process) GetResult() string { func (p *process) GetResult() string {
if p.lines.Empty() && p.exitErr != nil { var lines []string
return p.exitErr.Error() for !p.lines.Empty() {
if item, err := p.lines.Get(1); err == nil {
lines = append(lines, item[0].(string))
} }
items, _ := p.lines.TakeUntil(func(item interface{}) bool { }
return true if len(lines) == 0 && p.exitErr != nil {
}) return p.exitErr.Error()
lines := make([]string, 0, len(items))
for _, item := range items {
lines = append(lines, item.(string))
} }
return strings.Join(lines, "\n") return strings.Join(lines, "\n")
} }
@ -181,35 +174,27 @@ func (p *process) refreshVersion() {
} }
} }
func (p *process) Start() (err error) { func (p *process) Start() error {
if p.IsRunning() { if p.IsRunning() {
return errors.New("xray is already running") return errors.New("xray is already running")
} }
defer func() {
if err != nil {
p.exitErr = err
}
}()
data, err := json.MarshalIndent(p.config, "", " ") data, err := json.MarshalIndent(p.config, "", " ")
if err != nil { if err != nil {
return common.NewErrorf("Failed to generate xray configuration file: %v", err) return common.NewErrorf("Failed to generate xray configuration file: %v", err)
} }
configPath := GetConfigPath() configPath := GetConfigPath()
err = os.WriteFile(configPath, data, fs.ModePerm) if err = os.WriteFile(configPath, data, fs.ModePerm); err != nil {
if err != nil {
return common.NewErrorf("Failed to write configuration file: %v", err) return common.NewErrorf("Failed to write configuration file: %v", err)
} }
cmd := exec.Command(GetBinaryPath(), "-c", configPath) p.cmd = exec.Command(GetBinaryPath(), "-c", configPath)
p.cmd = cmd
stdReader, err := cmd.StdoutPipe() stdReader, err := p.cmd.StdoutPipe()
if err != nil { if err != nil {
return err return err
} }
errReader, err := cmd.StderrPipe() errReader, err := p.cmd.StderrPipe()
if err != nil { if err != nil {
return err return err
} }
@ -217,42 +202,20 @@ func (p *process) Start() (err error) {
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(2) wg.Add(2)
go func() { startReader := func(reader io.Reader) {
defer wg.Done() defer wg.Done()
reader := bufio.NewReaderSize(stdReader, 8192) scanner := bufio.NewScanner(reader)
for { for scanner.Scan() {
line, _, err := reader.ReadLine() p.lines.Put(scanner.Text())
if err != nil {
return
} }
if p.lines.Len() >= 100 {
p.lines.Get(1)
} }
p.lines.Put(string(line))
} go startReader(stdReader)
}() go startReader(errReader)
go func() { go func() {
defer wg.Done() defer wg.Wait()
reader := bufio.NewReaderSize(errReader, 8192) p.exitErr = p.cmd.Run()
for {
line, _, err := reader.ReadLine()
if err != nil {
return
}
if p.lines.Len() >= 100 {
p.lines.Get(1)
}
p.lines.Put(string(line))
}
}()
go func() {
err := cmd.Run()
if err != nil {
p.exitErr = err
}
wg.Wait()
}() }()
p.refreshVersion() p.refreshVersion()