Search code examples
mysqlnode.jsnode-mysql

Is the connect method in the NPM mysql module blocking?


The official mysql NPM package documentation for Node.js (here) makes the following suggestion for connecting to a database and executing a basic query:

var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'me',
  password : 'secret',
  database : 'my_db'
});

connection.connect();

connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

connection.end();

The connect method also takes an optional callback function, and the documentation provides the following example of that usage (ignore the comments in the example below; this example is actually trying to demonstrate something else):

var connection = require('mysql').createConnection({
  port: 84943, // WRONG PORT 
});

connection.connect(function(err) {
  console.log(err.code); // 'ECONNREFUSED' 
  console.log(err.fatal); // true 
});

connection.query('SELECT 1', function (error, results, fields) {
  console.log(error.code); // 'ECONNREFUSED' 
  console.log(error.fatal); // true 
});

In both cases, the query method is called after the connect method, and not, as might be expected, within the callback of the connect method. This seems to imply that the connect method is blocking (ie/ synchronous).

So I have a simple question, followed by some more nuanced questions:

Is the connect method in the NPM mysql module blocking?

If so, doesn't this go against the Node convention? Wouldn't the convention be to do a query within the callback passed to the connect method?

Finally, if the connect method is blocking and does go against Node convention, why did the designers of the mysql module decide to make connect blocking? What are the advantages of this approach? As the most popular mysql Node.js package, I'm sure there was a reason this approach was taken.


Solution

  • Good question!

    From the documentation I'm inferring that all queries you perform are queued up internally.

    When you call connection.connect(), it will (asynchronously) start setting up the connection to the server, and it'll also initialize a query queue where all queries that you want to run (by calling connection.query()) will get queued up.

    Once the actual connection has been established, it will perform the queued-up queries.

    Something similar happens with connection.end(): it will "...make sure all previously enqueued queries are still [performed] before sending a COM_QUIT packet to the MySQL server" (source).

    So it may look like both methods are blocking (synchronous), but in reality they aren't.