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
Fix timeout method #4324
Fix timeout method #4324
Conversation
@@ -869,7 +869,118 @@ module.exports = function (knex) { | |||
}); | |||
}); | |||
|
|||
it('.timeout(ms, {cancel: true}) should throw error if cancellation cannot acquire connection', async function () { | |||
it('.timeout(ms, {cancel: true}) should throw TimeoutError and cancel slow query in transaction', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is a copy of ".timeout(ms, {cancel: true}) should throw TimeoutError and cancel slow query" test with just the query enveloped into a transaction.
You can use this test to confirm that canceling a timeouted query does not work inside a transaction on current master
. The test will fail there. I've made as little as possible changes to the test, to make sure the cause is the transaction.
test/integration/query/additional.js
Outdated
}); | ||
}); | ||
|
||
it.skip('.timeout(ms, {cancel: true}) should throw error if cancellation cannot acquire connection', async function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We go around the connection pool for the cancellation query by purpose. As the pool will likely to be exhausted when queries start timeouting, which would prevent us from cancelling the query in the first place.
Therefore this test is contradictory and will fail, as an exhausted pool should not prevent the cancellation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove the test then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we ignore the pool limits for all dialects now, or test still makes sense for some of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we ignore the pool limits for all dialects now, or test still makes sense for some of them?
Query cancelling is supported ony for mysql and postgres, so this test was skipped for other dialects anyway:
// Only mysql/postgres query cancelling supported for now
if (!isMysql(knex) && !isPostgreSQL(knex)) {
return this.skip();
}
We can remove the test then
Maybe I'd rather turn the test arround that the query is indeed cancelled even if pool is exhausted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kibertoad Test refactored in 944e868
try { | ||
return await this.query(conn, { | ||
return await this._query(conn, { | ||
method: 'raw', | ||
sql: 'KILL QUERY ?', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bit of semantic difference between MySQL and Postgress:
KILL QUERY ?
in MySQL stops just the current query, but keeps the transaction active. So the user can send further queries to the same transaction and commit it eventually.SELECT pg_cancel_backend($1)
in Postress stops the current query, and also automaticaly rejects the transaction. So any further queries sent to the same transaction will fail and the transaction will be eventually rolled back.
Should we keep this semantinc difference? Or should we rather manually roll back the transaction in MySQL as well. If we decide either way, it won't be a breaking change, as the query cancellation didn't work in transactions so far anyway.
@elhigu @maximelkin @briandamaged This needs a careful review. |
The CI error seems unrelated. When I run the worflow on my fork, CI passed. Perhaps just hit the re-run button (I don't have access to it, so I can't re-run the workflow for the PR). |
a61d657
to
7f4285f
Compare
7f4285f
to
51b5191
Compare
Released in 0.95.3. |
Based on PR #2527 - rebased and added the fix for postgres too:
Timeout cancellation during transaction is fixed by using
acquireRawConnection
and_query
to bypass the transaction connection and cancel the query from a separate connection.fixes #2211