Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is using a Observable Singleton Class to handle network calls bad?

I have to develop a client/server game that uses a lot of network request to complete its task.

Both the client and the server receive multiple Command through socket. To handle these commands I created a NetworkHandler class that listens for new Input on a separate thread and that allow me to send new commands.

These "commands" are really heterogeneous and and are used by different classes. (For example the "client ready" command is used by the Main server class, while the "client wants a card" is used by the Game class).

So I created a CommandDispatcher class that listens to the NetworkHandler (Observable pattern) and that dispatch the different commands to the right receivers. (All through interfaces )

The problem is that every class that wants to register as a "command receiver" need to call the CommandDispatcher to set itself as a listener.

Because there are multiple class that needs this reference I'm thinking to transform the CommandDispatcher in a singleton class that could be accessed everywhere.

I know that Singleton and global class are bad and that I'm hiding a dependency and it will be difficult to test, but the only alternative I see is passing the CommandDispatcher from the Main Class to all the other classes.

Can you help me find a better solution? Thank you.

EDIT: I want to clarify that my app is a turn based game, so I don't have a large number of parallel request.

like image 617
user1305336 Avatar asked Nov 03 '25 01:11

user1305336


1 Answers

This is a common pattern that has been addressed many times in many environments.

The primary issue you need to address is the speed of despatch of the commands that arrive. You must ensure that no command can clog up the system otherwise you will get unpredictable response times. To achieve that you must do as little as possible to manage it's arrival.

The classic solution to this is for your network listener to do the minimum amount of work on the command and hand it off to a queue. Essentially you should merely grab the arriving message, place it in a queue and go back to listening. Don't even deserialise it, just throw it at the queue.

At the other end of the queue there can be one or more processes pulling commands out, constructing the appropriate objects and performing any functionality you want on them. This could be where your listeners should listen. Often all that will happen is the deserialised object will be despatched to another appropriate queue for handling so you may find an even more appropriate point to listen to at the other end of those queues.

Both the network listener and the command processor can often be implemented with thread pools.

Is using a Observable Singleton Class to handle network calls bad?

Bad? No - but it will not stand up to high throughput. You would be better to disassociate the network listener from the command dispatcher.

like image 131
OldCurmudgeon Avatar answered Nov 04 '25 17:11

OldCurmudgeon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!