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