Hi gophers:
I'm now making a golang server, holding lots of tcp connection, each client will login to the server,and send message to other client.
Server allocate an unique int64 sequce number to a client.
here's some part of code:
// current max sequense number
var seq int64 = 1
// lock for clients map
var connLock sync.RWMutex
var clients map[int64] *Connection = make(map[int64] *Connection, CONNSIZE)
type Connection struct {
seq int64
conn net.Conn
e *codec.Encoder
d *codec.Decoder
}
func addClient(conn net.Conn) *Connection {
connLock.Lock()
defer connLock.Unlock()
for {
seq++
if seq == 0 {
seq = 1
}
if clients[seq] == nil {
break
}
}
clients[seq] = &Connection{
seq: seq,
conn: conn,
}
return clients[seq]
}
func delClientBySeq(seq int64) {
connLock.Lock()
defer connLock.Unlock()
delete(clients, seq)
}
func sendToClient(seq int64, msg interface{}) {
var c *Connection
var sessNull bool
connLock.RLock()
defer connLock.RUnlock()
// finding connections:
...
// Encode will send to net.Conn
c.e.Encode(msg)
}
I have to lock everywhere:
1. when connection is made, we call addClient FROM EACH CONNECTION gorouting, hold rw lock
2. when connection is closed, we call delClientBySeq FROM EACH CONNECTION gorouting, hold rw lock
3. when client send message to other, call sendToClient FROM EACH CONNECTION gorouting, hold read-only lock
This may not cause a performance issue,because i have test it with 30000 connections and watch the the server with go tool pprof, sync.RWMutex Lock(),Unlock()... is not showing.
I'm not sure this is the right model for me, but this server is too much common, and i was wondering if there is a lock free style of this server?