Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[CONJS-240] following up correction, emptying prepare statement cache…
… on pool connection reset
  • Loading branch information
rusher committed Feb 14, 2023
1 parent 7ad4ecf commit c541864
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/connection.js
Expand Up @@ -337,6 +337,7 @@ class Connection extends EventEmitter {
const resetCmd = new Reset(
cmdParam,
() => {
conn.prepareCache.reset();
let prom = Promise.resolve();
// re-execute init query / session query timeout
prom
Expand Down
4 changes: 4 additions & 0 deletions lib/lru-prepare-cache.js
Expand Up @@ -38,6 +38,10 @@ class LruPrepareCache {
if (keyStr.length > 1) keyStr = keyStr.substring(0, keyStr.length - 1);
return 'info{cache:' + keyStr + '}';
}

reset() {
this.#lruCache.clear();
}
}

module.exports = LruPrepareCache;
127 changes: 127 additions & 0 deletions test/integration/test-pool.js
Expand Up @@ -9,6 +9,7 @@ const path = require('path');
const os = require('os');
const Proxy = require('../tools/proxy');
const { isXpand } = require('../base');
const { baseConfig } = require('../conf');

describe('Pool', () => {
const fileName = path.join(os.tmpdir(), Math.random() + 'tempStream.txt');
Expand Down Expand Up @@ -102,6 +103,132 @@ describe('Pool', () => {
}
});

it('prepare cache reuse', async () => {
const pool = base.createPool({
metaAsArray: true,
multipleStatements: true,
connectionLimit: 1,
prepareCacheLength: 2
});
await pool.execute('select ?', [1]);
const conn = await pool.getConnection();
const prepareCache = conn.prepareCache;
assert.equal(prepareCache.toString(), `info{cache:[${baseConfig.database}|select ?]}`);
conn.release();

await pool.execute('select ?', [1]);
assert.equal(prepareCache.toString(), `info{cache:[${baseConfig.database}|select ?]}`);

await pool.execute('select ? + 1', [1]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ? + 1],[${baseConfig.database}|select ?]}`
);

await pool.execute('select ? + 2', [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 2],[${baseConfig.database}|select ? + 1]}`,
prepareCache.toString()
);

await pool.execute('select ? + 3', [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 3],[${baseConfig.database}|select ? + 2]}`,
prepareCache.toString()
);

await pool.execute({ sql: 'select ? + 2' }, [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 2],[${baseConfig.database}|select ? + 3]}`,
prepareCache.toString()
);

await pool.execute({ sql: 'select 4' });
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select 4],[${baseConfig.database}|select ? + 2]}`
);

await pool.execute('select ?', [1]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ?],[${baseConfig.database}|select 4]}`
);
for (let i = 0; i < 10; i++) {
pool.execute('select ?', [i]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ?],[${baseConfig.database}|select 4]}`
);
}
pool.end();
});

it('prepare cache reuse with reset', async function () {
if (!shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(10, 3, 13)) this.skip();

const pool = base.createPool({
metaAsArray: true,
multipleStatements: true,
connectionLimit: 1,
prepareCacheLength: 2,
resetAfterUse: true
});
await pool.execute('select ?', [1]);
const conn = await pool.getConnection();
const prepareCache = conn.prepareCache;
assert.equal(prepareCache.toString(), `info{cache:[${baseConfig.database}|select ?]}`);
await conn.release();
assert.equal(prepareCache.toString(), `info{cache:}`);

await pool.execute('select ?', [1]);
assert.equal(prepareCache.toString(), `info{cache:[${baseConfig.database}|select ?]}`);

await pool.execute('select ? + 1', [1]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ? + 1],[${baseConfig.database}|select ?]}`
);

await pool.execute('select ? + 2', [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 2],[${baseConfig.database}|select ? + 1]}`,
prepareCache.toString()
);

await pool.execute('select ? + 3', [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 3],[${baseConfig.database}|select ? + 2]}`,
prepareCache.toString()
);

await pool.execute({ sql: 'select ? + 2' }, [1]);
assert.equal(
`info{cache:[${baseConfig.database}|select ? + 2],[${baseConfig.database}|select ? + 3]}`,
prepareCache.toString()
);

await pool.execute({ sql: 'select 4' });
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select 4],[${baseConfig.database}|select ? + 2]}`
);

await pool.execute('select ?', [1]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ?],[${baseConfig.database}|select 4]}`
);
for (let i = 0; i < 10; i++) {
pool.execute('select ?', [i]);
assert.equal(
prepareCache.toString(),
`info{cache:[${baseConfig.database}|select ?],[${baseConfig.database}|select 4]}`
);
}
pool.end();
});

it('pool batch stack trace', async function () {
if (process.env.srv === 'skysql' || process.env.srv === 'skysql-ha') this.skip();
const pool = base.createPool({
Expand Down

0 comments on commit c541864

Please sign in to comment.