mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-24 21:46:07 +00:00
2bb29468d8
* perf(xray): compile log/traffic regexps once at package scope GetTraffic recompiled two stats regexps on every traffic tick, and LogWriter.Write recompiled two more on every log line. Hoist all four to package-level vars so they compile once at load instead of per call on hot paths. * fix(xray): guard LogWriter.lastLine against the GetResult reader race Write is driven by the Xray process goroutine while Process.GetResult reads lastLine from the caller's goroutine, so the unsynchronized field is a data race under `go test -race`. Add an RWMutex and route every write through setLastLine; GetResult reads via LastLine(). * fix(xray): bound handler gRPC calls with a deadline AddInbound, DelInbound and the AddUser AlterInbound call used context.Background(), so a hung core connection could block the caller indefinitely (for example while the process restart lock is held). Give them a 10s deadline (handlerRPCTimeout) and a nil-client guard, matching the other handler operations.
37 lines
859 B
Go
37 lines
859 B
Go
package xray
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
// TestLogWriterLastLineConcurrent exercises the LogWriter from multiple
|
|
// goroutines: Xray drives Write while another goroutine (Process.GetResult)
|
|
// reads the last line. Run under `go test -race` this fails on an unguarded
|
|
// lastLine field and passes once the access is serialized.
|
|
func TestLogWriterLastLineConcurrent(t *testing.T) {
|
|
lw := NewLogWriter()
|
|
const writers, readers, iterations = 4, 4, 500
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(writers + readers)
|
|
|
|
for i := 0; i < writers; i++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
for j := 0; j < iterations; j++ {
|
|
_, _ = lw.Write([]byte("2024/01/01 00:00:00.000000 [Info] connection accepted"))
|
|
}
|
|
}()
|
|
}
|
|
for i := 0; i < readers; i++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
for j := 0; j < iterations; j++ {
|
|
_ = lw.LastLine()
|
|
}
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
}
|