I'm trying to build mmorpg server for academic purposes, so I ran into arcitecture difficulties.
There are five parts of my program: connect-listener, readers, writers, client-holder, handler. All of them communicate to each other via crossbeam-channels.
A thread with for-loop for getting new connection streams. When new stream received, I create Client structure with some data, create Reader and Writer with TcpStreams and some encoding staff.
Send Reader and client's login to readers thread via channel.
Send Writer and client's login to writers thread via channel.
Send just created Client to client-holder thread via channel.
A special thread with HashMap<String(client's login), Reader> and loop, that try receive message from channel, then try to read data from all readers (non blocking), then sleep a little (no need to use 100% cpu), repeat. From channel we can get message to add or remove reader (if new client connected or someone disconnected). From Readers we get data from sockets, when we got it, send to handlers channel message with received data (Vec) and client's login.
A special thread with HashMap<String(client's login), Writer> and loop, that try receive message from channel with waiting on channel.recv(). Message can say to add or remove writer from HashMap or to write data (Vec) with Writer to stream.
A thread with Arc<Mutex<HashMap<String, Arc<Mutex>>>> (I know that's crazy and I need help with that too), String again for login. Here is a loop with channel.recv(), can receive messages to add or remove clients to HashMap.
A thread (I have 5 equal threads) with loop again with channel.recv(). Messages are always from Reader with client's login and received data Vec. I need to take client from that crazy Arc<Mutex<HashMap<String, Arc<Mutex>>>>, which exists here to (shared memory). So I lock whole HashMap, get client, lock it and work with it (I can change data in Client struct for example).
If player equips a sword (just in case), I receive a request through Reader, pass it to Handler. Then I need to change data in Client struct (mark sword equipped) and send to player's Writer that sword was equipped. But that is not all: I need to go through all clients (in that crazy HashMap), find client's players nearby and send them information that player near them equipped sword.
The problem is in that HashMap. I need to keep all connected clients and work with them (and modify). But even when Server got new connected client, I need to lock HashMap to add element, even if I would use RwLock, here I need write lock here. And in that case all of my handlers will wait.
My question is where I do something wrong, what should I use or what should I read.