Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port mysql plugin to support mysql2 #607

Merged
merged 5 commits into from
Nov 30, 2017

Conversation

julienvincent
Copy link
Contributor

This PR adds support for the mysql2 npm module (as per #582).

I am unsure on how to get the test suite up and running correctly, if someone could point me in the right direction I'd be happy to also write tests for the added plugin 👍

I will put comments on the relevant lines that changed from plugin-mysql.js

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Nov 27, 2017

function createCreateQueryWrap(api) {
return function createQueryWrap(createQuery) {
return function createQuery_trace(sql, values, cb, config) {

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

}
api.wrapEmitter(query);
if (query.onResult) {
query.onResult = wrapCallback(api, span, query.onResult);

This comment was marked as spam.

shimmer.unwrap(Pool.prototype, 'getConnection');
}
}
];

This comment was marked as spam.


var shimmer = require('shimmer');

var SUPPORTED_VERSIONS = '^1.3.5';

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

@kjin kjin self-requested a review November 27, 2017 15:54
@kjin
Copy link
Contributor

kjin commented Nov 27, 2017

Thanks for the PR! I'm taking a look now... in the meantime, there's a script bin/docker-trace.sh that contains commands for launching docker containers for each of these databases. To make unit tests work you'll need to have all four services running. This should be the only pre-requisite to running unit tests with npm test.

As the APIs are similar it may be sufficient to edit test/plugins/test-trace-mysql.ts to make it so that every unit test is run twice, once for mysql and mysql2 each. The mysql library is currently being loaded from a fixture directory named at fixtures/mysql2, which might be confusing -- this refers to mysql@2. You should probably rename it so that there are co-existing fixtures mysql-2 and mysql2-1.

If you don't have time to do this that's fine, don't hesitate to let me know and I will update the tests.

@julienvincent
Copy link
Contributor Author

Great! That sounds simple enough - I will finish up the tests tomorrow morning then 👍


var shimmer = require('shimmer');

var SUPPORTED_VERSIONS = '^1.3.5';

This comment was marked as spam.

file: 'lib/connection.js',
versions: SUPPORTED_VERSIONS,
patch: function(Connection, api) {
shimmer.wrap(Connection, 'createQuery', createCreateQueryWrap(api));

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.


function createCreateQueryWrap(api) {
return function createQueryWrap(createQuery) {
return function createQuery_trace(sql, values, cb, config) {

This comment was marked as spam.

@julienvincent
Copy link
Contributor Author

I'm getting the following failed test when running locally:

  1) test-trace-connect
       should remove trace frames from stack:

      Uncaught AssertionError [ERR_ASSERTION]: 'Namespace.runAndReturn [as runAndReturn]' == 'middleware'
      + expected - actual

      -Namespace.runAndReturn [as runAndReturn]
      +middleware

      at ClientRequest.<anonymous> (/Users/julienvincent/code/cloud-trace-nodejs/test/plugins/test-trace-connect.ts:127:16)
      at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:565:21)
      at HTTPParser.parserOnHeadersComplete (_http_common.js:116:23)
      at Socket.socketOnData (_http_client.js:454:20)
      at addChunk (_stream_readable.js:252:12)
      at readableAddChunk (_stream_readable.js:239:11)
      at Socket.Readable.push (_stream_readable.js:197:10)
      at TCP.onread [as _originalOnread] (net.js:589:20)
      at TCP.onread (/Users/julienvincent/code/cloud-trace-nodejs/node_modules/async-listener/glue.js:188:31)

As far as I can see this has nothing to do with the changes I made. Any ideas?

@kjin
Copy link
Contributor

kjin commented Nov 28, 2017

Oops - this test failure has to do with the GCLOUD_TRACE_NEW_CONTEXT environmental variable; this should be set to 1. Sorry -- that slipped my mind earlier.

@julienvincent
Copy link
Contributor Author

I'm struggling with a strange issue now that I can't piece together. @kjin Perhaps you could help me understand whats happening here:

Defining a patcher for lib/pool.js of mysql2 breaks the constructor of Pool. This seems to happen whether or not I alter properties on its prototype - simply defining the patcher breaks it. The error I get in the tests is as follows:

  test-trace-mysql-2
    ✓ should perform basic operations
    ✓ should propagate context
    ✓ should remove trace frames from stack
    ✓ should work with events
    ✓ should work without events or callback (54ms)
    ✓ should perform basic transaction

  test-trace-mysql2-1
    1) "before all" hook
    2) "after all" hook


  6 passing (368ms)
  2 failing

  1) test-trace-mysql2-1
       "before all" hook:
     TypeError: Pool is not a constructor
      at Object.module.exports.createPool (test/plugins/fixtures/mysql2-1/node_modules/mysql2/index.js:17:10)
      at Context.<anonymous> (/Users/julienvincent/code/cloud-trace-nodejs/test/plugins/test-trace-mysql.ts:44:20)

  2) test-trace-mysql2-1
       "after all" hook:
     TypeError: Cannot read property 'end' of undefined
      at Context.<anonymous> (/Users/julienvincent/code/cloud-trace-nodejs/test/plugins/test-trace-mysql.ts:48:11)

and the exports of the plugin-mysql2.ts look as follows:

module.exports = [
  {
    file: 'lib/connection.js',
    versions: SUPPORTED_VERSIONS,
    patch: function(Connection, api) {
      shimmer.wrap(Connection, 'createQuery', createCreateQueryWrap(api));
    },
    unpatch: function(Connection) {
      shimmer.unwrap(Connection, 'createQuery');
    }
  },
  {
    file: 'lib/pool.js',
    versions: SUPPORTED_VERSIONS,
    patch: function(Pool, api) {
      // shimmer.wrap(Pool.prototype, 'getConnection',
      //              createWrapGetConnection(api));
    },
    unpatch: function(Pool) {
      // shimmer.unwrap(Pool.prototype, 'getConnection');
    }
  }
];

As you can see the patcher itself is not doing anything to Pool, this leads me to believe that something is happening within trace-plugin-loader.ts to cause this - though I can't see anything obvious that would cause this.

What I have done for now is change the pool patcher to target index.js which seems to work as expected, but I would still like to figure out whats happening here as it may reveal a bug in the plugin loader.

@julienvincent
Copy link
Contributor Author

julienvincent commented Nov 29, 2017

I don't think the tests that just failed on CircleCI were due to my changes - could you retry the build? I think circle was just slow and the timeout was exceeded.

@kjin
Copy link
Contributor

kjin commented Nov 30, 2017

@julienvincent I looked into the lib/pool.js patch issue you mentioned yesterday... I'm as baffled as you are. Investigating more today.

@julienvincent
Copy link
Contributor Author

I can say that I was able to patch that file fine while using version 2.2.0 of this module within my personal project (before starting this PR) and using the above plugin as an external plugin. Perhaps a change has been made since then to cause this?

@kjin
Copy link
Contributor

kjin commented Nov 30, 2017

Yes, it seems like it.

I think I understand the issue now -- will open a bug imminently. In the meantime, if the patch to index.js is sufficient, let's use that.

@julienvincent
Copy link
Contributor Author

Aha! Circular references - that makes sense now.

Yes the patch to index.js seems to work fine 👍

Copy link
Contributor

@kjin kjin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks! (I'll fix #618, and use your initial version patching lib/pool.js to see if it works)

@kjin kjin merged commit b6bd7c2 into googleapis:master Nov 30, 2017
@julienvincent julienvincent deleted the feature-add-plugin-mysql2 branch November 30, 2017 22:49
@julienvincent
Copy link
Contributor Author

Great! Thanks for your help, I will follow #618 for updates 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants