mirror of
https://github.com/HDT3213/godis.git
synced 2025-10-03 07:56:38 +08:00
bugfix: Resolved a concurrency issue with ClientCounter. Previously, directly decrementing ClientCounter in multiple goroutines (ClientCounter--) could lead to data races and inconsistencies. Now, by using atomic.AddInt32(&ClientCounter, -1), we ensure safe updates to the counter, maintaining its accuracy and stability even in high concurrency scenarios.
This commit is contained in:
@@ -51,3 +51,38 @@ func TestListenAndServe(t *testing.T) {
|
|||||||
closeChan <- struct{}{}
|
closeChan <- struct{}{}
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientCounter(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
closeChan := make(chan struct{})
|
||||||
|
listener, err := net.Listen("tcp", ":0")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
addr := listener.Addr().String()
|
||||||
|
go ListenAndServe(listener, MakeEchoHandler(), closeChan)
|
||||||
|
|
||||||
|
sleepUntil := time.Now().Add(3 * time.Second)
|
||||||
|
subtime := func() time.Duration {
|
||||||
|
return sleepUntil.Sub(time.Now())
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
go func() {
|
||||||
|
conn, err := net.Dial("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
time.Sleep(subtime())
|
||||||
|
}()
|
||||||
|
time.Sleep(5 * time.Microsecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
if ClientCounter != 0 {
|
||||||
|
t.Errorf("client counter error: %d", ClientCounter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -11,6 +11,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -26,7 +27,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ClientCounter Record the number of clients in the current Godis server
|
// ClientCounter Record the number of clients in the current Godis server
|
||||||
var ClientCounter int
|
var ClientCounter int32
|
||||||
|
|
||||||
// ListenAndServeWithSignal binds port and handle requests, blocking until receive stop signal
|
// ListenAndServeWithSignal binds port and handle requests, blocking until receive stop signal
|
||||||
func ListenAndServeWithSignal(cfg *Config, handler tcp.Handler) error {
|
func ListenAndServeWithSignal(cfg *Config, handler tcp.Handler) error {
|
||||||
@@ -88,7 +89,7 @@ func ListenAndServe(listener net.Listener, handler tcp.Handler, closeChan <-chan
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
waitDone.Done()
|
waitDone.Done()
|
||||||
ClientCounter--
|
atomic.AddInt32(&ClientCounter, -1)
|
||||||
}()
|
}()
|
||||||
handler.Handle(ctx, conn)
|
handler.Handle(ctx, conn)
|
||||||
}()
|
}()
|
||||||
|
Reference in New Issue
Block a user