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
Preferred way to handle reconnect #2113
Comments
|
I believe this would be best handled in sequelize - at least we could retry a number of times and otherwise give up. I believe we could handle this rather nicely actually. Each dialect returns an instance of Sequelize.ConnectionLost when the connector lib gives and error, and the abstract connector manager handles trying to reconect. It should be as simple as just trying the query again, since that should try to fetch a new connection (provided that the previous query flagged its connection as broken properly). Flagging this as a feature request |
|
@janmeier Thanks that would be amazing. |
|
|
|
+1 This is definitely something desired. Thanks! |
|
👍 for this feature. |
|
👍 Waiting too |
|
+1 I'm gonna add a bounty for this one |
|
+1 |
|
This feature is so important in actual production setting, where databases run on completely different hosts, and having those hosts hiccup completely wreck everything because sequelize won't reconnect even though it should be able to. I can't even emphasize how much this should be the most important feature to add as soon as possible, even just an |
|
@Pomax so effectively retry queries anytime we get a connection type error? (Retrying a query should try to initiate a new connection assuming the old one was marked invalid which it should have). That would necessarily be so hard to implement, could happen at query level and look for a global or local option. |
|
(if you are willing to be a guinea pig i'd be happy to write something like that, we've just been hesitant since it would be hard to have unit or regression tests for, so we need someone to battle test it, and for some reason i've never really encountered it). |
|
Small issue of transactions of course, they would likely need to be retried at the transaction level rather than the query level. |
|
Yeah, as just a simplest option "retry ad infinitum, or the user explicitly set a retry count" would be amazingly useful already. My api.nihongoresources.com has a database hosted not just on a different machine, but by a different organization, and it drops every so often because the machine it's on power cycles fairly often (few weeks, if not days sometimes), which absolutely destroys API functionality. If you want a guinea pig: it can't get worse than what it's doing right now, hook me up ;) This would be amazing to have: ("or true" because I'll even just take a plain old "just try to reconnect forever" over "all things now broken" =D) Transaction failure could be left up to the user really: |
|
Great :) I'll see if i can take a look at this soon. |
|
that's how transactions should work though, if it's a true transaction? if any part of a transaction fails, up to and including the commit, it should be discarded. |
|
@Pomax Right but query retrying would have to be disabled inside a transaction then :) And then it might make sense to retry the entire transaction if one query had a connection error. Although now that i'm thinking about it queries inside a transaction run on the same connection so might not be an issue. |
|
Ahh, yes, very true. If the DBMS is smart enough to roll back on a broken connection or timeout, that should be fine (not sure off-hand what pg and mysql do there) |
|
+1 |
|
+1 this would be great |
|
Since this is still open any suggestions on how we should handle a database dropping out until it's implemented into Sequelize? |
|
@Joshua-F my solution was to use a fairly dumb try/catch probe (like a |
|
@Pomax that's a great idea! Do you have an example of how you rebuild the sequelize instance? Do you essentially wrap the construction in a factory function: var Sequelize = require('sequelize');
module.exports = function buildSequelize() {
var sequelize = new Sequelize('username', 'password');
sequelize.define('User', {
// ...
});
return sequelize;
};Or are you using an easier method that simply closes and reopens sequelize? (I would prefer that method if it exists) |
|
nope, that's what I do =) |
|
@mickhansen is there an updated solution or fix for this pending? I'm having this issue as well...great to see that it's been well captured in this thread. The 'wait_timeout' variable may be relevant as well, see: |
|
@dxdc I originally thought I had this problem and commented on this thread like two days ago, but deleted my comment when I found that the latest sequelize does tend to do this automatically every time that a query is requested. At least I found this true with using sequelize with mysql. |
|
thanks @AndrewFarley ; I'm still having this issue. As far as I can tell, it's connected to the wait_timeout variable in the MySQL settings. The default is 28800 (8 h), but this is too high for common web applications where a more realistic recommendation is 30-300 sec. |
|
@ashish277d No. If you have the above-mentioned version (4.11.1), the reconnection behavior is default. |
|
I couldn't see this feature/fix on the changelog, can anybody reference the appropriate commit for this? Thanks. |
|
|
I did the following testing:
According to my testing, it takes around 1 minute before a query can be sent to the database successfully. Is it possible to configure how quickly are those connections being re-established? |
|
it is still not working for me. I have latest version 4.13.8. |
I think Sequelize reconnects after a certain period of time (perhaps controlled by a timeout value?) instead of reconnect immediately, but I'm not sure about this. |
|
did anyone manage to get this working? it doesnt work for me either. |
|
Here's my thinking:
From what I understand the only missing piece (and the root of this issue) is that the retry around the queries will reuse the same connection, even if it died. I'll try to dig more into this and send a PR, but I think this might end up being a really simple fix - when retrying a query, yield the old connection and ask for a new one. This configuration will already retry the queries on connection errors, but it will fail forever because it reuses the old connection: // this goes to retry-as-promised for queries
retry: {
match: [
/SequelizeConnectionError/,
/SequelizeConnectionRefusedError/,
/SequelizeHostNotFoundError/,
/SequelizeHostNotReachableError/,
/SequelizeInvalidConnectionError/,
/SequelizeConnectionTimedOutError/
],
name: 'query',
backoffBase: 100,
backoffExponent: 1.1,
timeout: 60000,
max: Infinity
}When a query fails due to a connection error, retry with exponential backoff with a max time of 60 seconds. This seems like a really robust way to manage reconnects/retries, just needs that fix for the connections and this should close a bunch of tickets around this. Edit: PR submitted - #8961 |
|
im still unable to get this working... according to the documentation (http://docs.sequelizejs.com/class/lib/sequelize.js~Sequelize.html) it states that there are defaults set for all the pool options.. my repro steps using mariadb 10.2:
even after a few minutes it seems as though the connections arent reconnecting and im unable to query the db. my config looks like so... this recently affected us because there was an unexpected DB crash with our AWS RDS instance. |
|
@stringbeans |
|
I ended up listening for a |
|
After a lot testing, I can confirm that this issue still exists under replication mode.
|
|
My connection to MySQL is lost and never recovers. Sequelize: 4.41.1 |
|
@kingjerod would you mind posting a code snippet for your middleware hack? |
|
My processes are managed with PM2 so exiting will cause PM2 to restart the process. There is another middleware before this that catches errors and sets the ctx.body.error message. There is some typescript in here that can be easily stripped out. |
@contra Quick question: I see that the documentation mentions the |
|
@gwilakers Yeah, they are undocumented. BTW for retrying queries - this bug is currently breaking some cases: #10453 |
|
@contra Okay, thanks for confirming. Ironically, I just subscribed to that issue this morning haha. Thanks for the update. |
|
This doesn't seem to work in one specific case:
The connection to the database is established fine and sequelize is operational, however model sync has been skipped and is never retried. Any ideas if I'm doing something wrong? |
In case the db connection is lost, we need to reconnect to the database. I couldn't find a preferred way to handle this issue. Do you have a best practice? The issue can be solved on various ways:
Thanks in advance
The text was updated successfully, but these errors were encountered: