Uploaded image for project: 'MariaDB Connector/node.js'
  1. MariaDB Connector/node.js
  2. CONJS-361

Prepared statement never executed (connector hangs)

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 3.5.3
    • 3.5.4
    • other
    • None

    Description

      We just stumbled onto something quite weird with the CJS package that the 3.5 series introduced.

      We use MariaDB NodeJS connector in a (somewhat complex) app, written in CommonJS, that connects to various data sources; to help with these we have crafted in it a lightweight abstraction class that we instantiate for each connection. Its workflow is simple - connects to the DB, prepare the statement, cache its handler, run it (and then store it around for eventual reuse in the same session). We keep things simple - no connection pools, just short-lived connections that are created on-demand and get recycled as soon as they do their job.

      This has worked well for many years, first with the mysql2 connector and later the mariadb one up to and including the 3.4 series. When we dropped in a 3.5 version (initially 3.5.1, later we tried 3.5.3), everything just hung. After some tracing, we were puzzled to find that the statement was prepared, but it never ran. Nothing on the wire - the DB responds with the ID of the prepared statement, the connector sees it as a Promise and then just complete silence; the promise neither fulfils nor fails, as if it was (and maybe it was) never triggered.

      After some deconstruction we were even more surprised to distil this down to the odd case, described below. Naturally, to connect to a DB, we need some settings; we read them from a JavaScript file via a simple require(). Historically, it contained an object with several properties - one for each supported DB configuration, like this:

      var mariadb =

      { host: 'mariadb.example.com', user: ... }

      ;
      var config =

      { mariadb: mariadb, }

      module.exports = config;

      With the above file, 3.4 and previous versions work fine; 3.5 hangs forever after preparing the statement. (In both versions the .query() method still works, but we rarely use it for obvious reasons). In our many attempts to figure out why 3.5 hangs, we decided randomly to simplify the configuratrion... and voila, version 3.5 also worked (naturally, we changed our code to account for the differet structure of the config):

      var mariadb =

      { host: 'mariadb.example.com', user: ... }

      ;
      module.exports = mariadb;

      Further down this rabbit hole, we attempted to play with the configuraiton after it was loaded:

      • Serialising and and the deserialising it did not fix the issue.
      • Making a deep copy of the "mariadb" key of the "faulty" configuration object also did not fix the issue.

      Attached here are two distilled down PoC with comments - for us it perfectly showcases the issue, albeit we're completely unable to explain why a nested object in the configuration hangs the connector and why it specifically hangs the execution of a prepared statement after a successful DB connection is established. One of them uses the callback interface you provide and the other uses a dynamic import with promises; both fail the same way with 3.5 and work fine with 3.4.

      Attachments

        1. poc.js
          2 kB
        2. poc2-1.js
          1 kB

        Activity

          People

            diego dupin Diego Dupin
            Totin Assen Totin
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Git Integration

                Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.