Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB PHP header data timeout

Tags:

php

mongodb

My development team is having trouble accessing a remote MongoDB database from their local development environments.

The remote Ubuntu development server is running the newest v2.4.3 of MongoDB and PHP 5.3 with the mongo-php-driver v1.3.7 built for PHP 5.3. mongodb.conf is nearly empty except for basic path setup. There are currently no shards or replica sets.

All team members are using OSX 10.8, PHP 5.3, and have the mongo-php-driver v1.3.7 built for PHP 5.3. Some team members use XAMPP, others are using the built-in OSX AMP stack. We test on all major desktop browsers.

Whenever a page needs to grab data from Mongo, we start by calling this connection function:

public static function connect($server, $db)
{
    $connection = new MongoClient(
        "mongodb://{$server}:27017", 
        array(
            "connectTimeoutMS" => 20000, 
            "socketTimeoutMS" => 20000
        )
    );

    return $connection->$db;
}

However, nearly 30% of page loads are experiencing the following error:

Failed to connect to: www.development-server.com:27017: send_package: error reading from socket: Timed out waiting for header data

It seems that a large portion of those errors occur when refreshing a page, rather than navigating to a new page, but that's more of a guess than a fact. I've checked everyone's php.ini file and confirmed that default_socket_timeout = 60 is set.

The development server also hosts a copy of the site, but has never thrown the error, presumably since it's only calling localhost to get there. When I installed MongoDB locally, the errors also went away.

This really appears to be a timeout issue, but I cannot find any further settings, parameters, or configurations to adjust the expiry period. Are there any?

like image 592
andvari101 Avatar asked Nov 12 '22 05:11

andvari101


1 Answers

The response from @hernan_arg got me thinking about another possibility. Instead of relying on the one-and-only connection attempt to succeed (which seems to take forever), is it acceptable to stick the connection in a loop until it succeeds?

public static function connect($server, $db)
{
    $connection = null;

    try {
        $connection = new MongoClient("mongodb://{$server}");
    } catch (MongoConnectionException $e) {
        return self::connect();
        exit;
    }

    return $connection->$db;
}

Logging indicates that when the connection does fail, it fails quickly and the loop will establish a new connection in a much more timely manner than the infinite timeout does. Supposing the database becomes unreachable I'm assuming I can rely on PHP execution timeout to eventually kill the process.

like image 64
andvari101 Avatar answered Nov 15 '22 12:11

andvari101