I'm using Codeigniter and every time that I refresh my index page, my application opens a new connection. I tried to Singleton my connection class, but it continues opening a new connection.
Mongolib.php
class Mongolib extends MongoClient
{
var $db;
public function __construct()
{
$ci =& get_instance();
$ci->load->config('mongo');
$server = $ci->config->item('mongo_server');
$dbname = $ci->config->item('mongo_dbname');
if ($server)
{
parent::__construct($server);
}
$this->db = $this->$dbname;
}
}
When i tried Singleton:
MongoDB.php (in third_party folder)
class MongoApi {
static protected $_instance;
protected $db = null;
final protected function __construct() {
$m = new MongoClient();
$this->db = $m->selectDB( "mydb" );
}
static public function getInstance() {
if (!(self::$_instance instanceof self)) {
self::$_instance = new self();
}
return self::$_instance;
}
public function getConnection() {
return $this->db;
}
final protected function __clone() { }
}
Mongolib.php (in library folder)
require MY_PATH . '/application/third_party/MongoDB.php';
class Mongolib
{
var $db;
public function __construct()
{
$this->db = MongoApi::getInstance()->getConnection();
}
}
When i refresh my page and run db.serverStatus() it opens a new connection...
"connections" : {
"current" : 4,
"available" : 2044,
"totalCreated" : NumberLong(7)
},
Mongo drive version - 1.6.0-dev
A singleton does not outlast the request life cycle. What you are looking for is http://php.net/manual/en/features.persistent-connections.php. I would read over the page and familiarize yourself with the workflow. Furthermore it looks like you are using an older mongo db driver. Read over this here for information related to your issue http://php.net/manual/en/mongo.connecting.persistent.php. All in all edit your connect to look something like this...
new MongoClient("mongo_server", array("persist" => "x"));
Looking at the documentation further here http://php.net/manual/en/class.mongoclient.php persistant is actually supose to be a true/false value... I am not sure why they use "x" which will convert to true as it's a convoluted example. I would check and see if...
array("persist" => true);
works as this is much cleaner code to read.
The MongoDB driver itself manages a connection pool. For every request, a connection is opened. It is supposed to be that way, as server side cursors are attached to the connection it created.
The connections are kept alive for a certain amount of time (to be exact either MongoClient's connectTimeoutMS
or PHP's default_socket_timeout
, whichever occurs first), in which they can be reused, but sometimes aren't, for example, if not properly marked as not used any more. You should investigate here.
The reason for this behavior is that setting up a TCP connection adds quite some latency to a request, even more so if authentication is involved.
A connection is rather cheap from the server side: 1MB of stack memory, plus some k of overhead. A mongod is designed to deal with quite some connections. A couple of hundred aren't unusual in the typical production environment.
HTH.