AsyncDatabaseManager - Mini-IT/SnipeWiki GitHub Wiki
In case when you need to make the slow SQL query into the database or you need to do SQL queries in the most efficient way, the cache server provides the asynchronous database manager. The manager operates a given number of threads (specified in the cache server configuration file with "asyncDatabase.threads" variable) that each open up a given number of asynchronous connections to the database through the asynchronous Postgres API ("asyncDatabase.connectionsPerThread" configuration variable). When receiving a new request through one of the API methods of snipe.cache.AsyncDatabaseManager
class it is passed into the manager queue. One of the manager threads picks it up and sends to the database. When the query is done, the callback is called. You can specify which thread to run the callback in: one of asynchronous worker threads or in the same asynchronous database manager thread that handled the request.
This method executes the given query and then runs the callback in one of the asynchronous worker threads.
Note: You cannot pass multiple queries to this method as a single semicolon-separated string.
Usage example:
function testCall(c: SlaveClient, params: Params): Dynamic
{
var id = params.getInt('id');
server.asyncDatabaseManager.query(c.id, params,
"SELECT * FROM Users WHERE ID = " + id, test2);
return { errorCode: 'ok' };
}
function test2(async: AsyncWorkerThread, serverID: Int, params: Dynamic)
{
// "__result" field is inserted by the manager thread and contains the query result
var res: ResultSet = params.__result;
// ...
}
This method executes the given query and then runs the callback in the same asynchronous database manager thread. This is intended to be used for the callbacks that do not have any serious work in them.
Note: You cannot pass multiple queries to this method as a single semicolon-separated string.
Usage example:
function testCall(c: SlaveClient, params: Params): Dynamic
{
var id = params.getInt('id');
server.asyncDatabaseManager.query2(c.id, params.params,
"SELECT * FROM Users WHERE ID = " + id, test2);
return { errorCode: 'ok' };
}
// Note the different function arguments for this callback
function test2(serverID: Int, res: ResultSet, params: Dynamic)
{
// ...
}
This method executes the queries given in an array and then runs the callback once in one of the asynchronous worker threads.
Usage example:
function testCall(c: SlaveClient, params: Params): Dynamic
{
var id = params.getInt('id');
server.asyncDatabaseManager.queryArray(serverID, params, [
"INSERT INTO Users (ID) VALUES (" + id + ")",
"INSERT INTO UserQuests (ID) VALUES (" + id + ")",
"INSERT INTO UserRatings (ID) VALUES (" + id + ")"
], test2);
return { errorCode: 'ok' };
}
function test2(async: AsyncWorkerThread, serverID: Int, params: Dynamic)
{
// ...
}
This method deserves a special mention. It is a shortcut for sending a SQL query to the cache server for execution in one of the asynchronous database manager threads. It returns immediately. After the query execution is completed its results are returned to this slave server into the callback given as an argument.
Note: You cannot pass multiple queries to this method as a single semicolon-separated string.
For example:
server.cacheConnection.asyncQuery(c.connectionID,
"SELECT ID, NetworkType, NetworkID FROM Users WHERE ID IN (" +
array.join(",") + ")", { test: 1 },
function (client, res: List<Dynamic>, params: Dynamic)
{
if (client == null)
return;
if (res == null)
res = new List();
client.response('user.getFriends',
{ errorCode: 'ok', list: res, test: params.test });
}
);
In this example we pass the list of user IDs into the query that is ran in one of the asynchronous database manager threads on the cache server. The results of the query will be passed back to the slave server into the given callback as an argument. We also supply the client connection ID to the API. That will allow the callback to use the client instance. We can also pass additional parameters object to the callback.
Note the check for client variable to be null in the callback. During the time that passed from the initial call to the response the client might have been disconnected.