Async (non-blocking) Postgres Database Handler
by Danni · 06/01/2008 (2:24 pm) · 4 comments
This post is out of date, check the completed resource here.
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=14975
After looking at how wonderfully C looking the async API would be I figured a better solution would be threading with a pool handler. So here it is! Basically the way this works is one can create a pool of threads each with their own connection into the PGSQL database. You execute a query to the pool and one of the threads picks it up then processes it returning to a callback (C++ or TS). In the callback you have full access to the result for the run of the callback.
Here is how i set mine up.
The Database connection arguments are now in the prefs.cs files;
In TS you can query anywhere with the following;
C++ is almost identical.
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=14975
After looking at how wonderfully C looking the async API would be I figured a better solution would be threading with a pool handler. So here it is! Basically the way this works is one can create a pool of threads each with their own connection into the PGSQL database. You execute a query to the pool and one of the threads picks it up then processes it returning to a callback (C++ or TS). In the callback you have full access to the result for the run of the callback.
Here is how i set mine up.
function createServer(%serverType, %mission)
{
.....
PGSQLPool::createPool();
.....
}The Database connection arguments are now in the prefs.cs files;
$pref::Server::Database::Database = "TGEA"; $pref::Server::Database::Host = "localhost"; $pref::Server::Database::Password = "test"; $pref::Server::Database::Port = "5432"; $pref::Server::Database::Threads = "2"; $pref::Server::Database::Username = "tgeauser";
In TS you can query anywhere with the following;
function getResult(%r)
{
%db = PGSQLPool::getPool();
%val = %db.getValue(%r, 0, 1);
echo("DATABASE GOT " @ %val);
}
function otherFunction()
{
%db = PGSQLPool::getPool();
%db.Exec("getResult", "SELECT * FROM tgea_test WHERE first = %s;", "something");
}C++ is almost identical.
void getResult(PGQuery* r,const void *user)
{
const char* val = r->getValue(0,1);
}
void function()
{
PGSQLPool* db = PGSQLPool::getPool();
int userval = 1;
db->Exec(&getResult, &userval, "SELECT * FROM tgea_test WHERE first = %s;", "something");
}
#2
06/01/2008 (5:42 pm)
That's really slick Danni.
#3
Thank you.
06/09/2008 (1:15 pm)
Danni, this looks like exactly what I need for some non-profit educational stuff that we are doing. I am about to try it with TGE, which is the engine we are using. Do you foresee any problems with this? By the way, we use TGE because it seems to use less resources, and many of the target machines belong to schools which are often under powered. Thank you.
#4
06/09/2008 (4:26 pm)
It should work just fine, as long as TGE has good multithreading support. I think the big problem is that Con::executes must create a event instead of run the script directly, not sure if TGE does.
Torque 3D Owner Tony Richards