Original post

Hello everyone! I am writing my own Pub/Sub system. It must be able to store information about clients, topics, clients’ subscriptions, users (user is a group of clients). It is supposed to work as a storage of WebSocket (though it’s still available to use other transports) connections and should be able to send data as fast as possible.

Possible architecture may look as it’s shown below:

type Pubsub { clients map[string]*Client users map[string]map[*Client]struct{} inactiveClients map[string]time.Time invalidClients map[string]time.Time topics map[string]*topic subs map[string]map[string]subscription userSubs map[string]map[string]subscription mu sync.RWMutex }

As you see there is an inactiveClients field. It is used for delayed of clients (it’s used for reconnections and lost data recovery).

Data publishing requires RLock-ing of mu, thus subscribing to some topic has to stop sending. The behavior written above sounds very bad to me and I would be grateful to know what optimizations can be used to reduce mutex contention and to speed up the whole system.

P.S: I’ve heard of sharding, but I don’t know how to distribute Ids fast. For example, we have the following subscription request:

{

UserIDs: []string{"user1", "user2"},

ClientIDs: []string{"client1", "client2"},

Topics: []string{"chat1", "chat2"},

}

How to figure out which ids I should pass to which shard without extra allocations and fast?