Hi I have AppWarpS2 game server solution and Mongo db service that we are currently developing and testing right now.
My question is around room management in regard to mongo client db connection with the java driver.
Server holds static client to our monngodb service:
public class ClientSingleton
{
// Client instance singleton as volatile (modified by different threads &
// not cached locally: all reads and writes go straight to "main memory")
private volatile static ClientSingleton uniqueInstance;
// The MongoClient class is designed to be thread safe and shared among threads.
// We create only 1 instance for our given database cluster and use it across
// our application.
private MongoClient mongoClient;
private MongoClientOptions options;
private MongoCredential credential;
private final String password = "xxxxxxxxxxxxxxxxxxxxxxxx";
private final String host = "xx.xx.xx.xx";
private final int port = 38180;
/**
*
*/
private ClientSingleton()
{
// Setup client credentials for DB connection (user, db name & password)
credential = MongoCredential.createCredential("xxxxxxxxxxx", "OurDB", password.toCharArray());
// Setup client options
// Don't to leave socketTimeout and connectTimeout at defaults (eg infinite) if connection hangs
// for some reason will get stuck forever!
// Set number of milliseconds the driver will wait before a connection attempt is aborted, for connections
// made through a Platform-as-a-Serivce (PaaS) it is advised to have a higher timeout (e.g. 25 seconds)
// Set number of milliseconds the driver will wait for a response from the server for all types of
// requests (queries, writes, commands, authentication, etc.).
// ConnectionsPerHost
// ThreadsAllowedToBlockForConnectionMultiplier maximum number of threads that may be waiting
// for a connection to become available from the pool.
options = MongoClientOptions.builder()
.connectTimeout(25000)
.socketTimeout(60000)
.connectionsPerHost(100)
.threadsAllowedToBlockForConnectionMultiplier(5)
.build();
try
{
// Create client (server address(host,port), credential, options)
mongoClient = new MongoClient(new ServerAddress(host, port),
Collections.singletonList(credential),
options);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
}
/**
* Double checked dispatch method to initialise our client singleton class
*
*/
public static ClientSingleton getInstance()
{
if(uniqueInstance == null)
{
synchronized (ClientSingleton.class)
{
if(uniqueInstance == null)
uniqueInstance = new ClientSingleton();
}
}
return uniqueInstance;
}
/**
* @return our mongo client
*/
public MongoClient getClient() {
return mongoClient;
}
}
I understand failure to properly utilise connection pooling is one major “gotcha” that greatly impact Mongo db performance. Also creating new connections to the db is expensive and I should try and re-use existing connections. I've not left socket timeout and connect timeout at defaults (eg infinite) if connection hangs for some reason I think it will get stuck forever! I set number of milliseconds the driver will wait before a connection attempt is aborted, for connections made through a Platform-as-a-Serivce it is advised to have a higher timeout (e.g. 25 seconds). I also set number of milliseconds the driver will wait for a response from the server for all types of requests (queries, writes, commands, authentication, etc.).
The mongodb holds question data for quiz game. Server creates room for quiz game from game table properties (based on your trivia quiz example) and moves players to room which calls mongo singleton and gets reference to client and db.
Following a game or I should say after an room idle time the room get destroyed - this idle time is currently set to 60 mins. I believe that if connections per host is set to 100 then while this room is idle then it would be using valuable connection resources as room holds client connection to db. If I have several hundred concurrently connected games and each accessing the db to pull the questions then maybe following that request free up the client connection for other rooms to use? How should this be done? I'm concerned about possible bottle necks here!
How could I clean up connections to db here as I understand that static rooms created in dashboard cannot get deleted? If server creates room that was created in dashboard can the server delete this room? If so how would I delete this room (what is the API) for this. If not then I think I should clean up the resource to client db connection following a successful retrieval of questions from db? Can this be done?