-
Notifications
You must be signed in to change notification settings - Fork 67
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
sqliteutil.Exec doesn't release prepare statements / stmt.Reset() after INTERRUPT #20
Comments
Good catch on Reset. It really should always be called, even after interrupt. I'm going to remove that condition so Reset always passes through to sqlite. I've also found another case for #18 that I have a patch coming for in a moment. |
According to the SQLite docs: Any new SQL statements that are started after the sqlite3_interrupt() call and before the running statements reaches zero are interrupted as if they had been running prior to the sqlite3_interrupt() call. When we detect a closed interrupt and return false from Step without resetting a statemnt, we leave open a statement. This means future calls to SetInterrupt don't succeed, because of an outstanding sqlite statement. To fix that conditon, reset stmts when we interrupt Step without calling into cgo. To fix the more general condition, reset any open statements on call to SetInterrupt. Finally, make sure Reset always resets, as discovered by Amos Wenger. For #18 For #20
@crawshaw #21 is slightly more annoying - it's not just It might be a good idea to make the
This might be too expensive for prod, so it would make sense to only enable it in debug and/or testing. But I think this would catch any other instances of #18 we have left. Also, are you interested in:
I can take care of either or both of these if that's something you'd want. |
Both of those are good, please send pull requests! (Out of interest, how long is the chao test?) |
(This is very hard to test.) For #20
I just had it failing against 7f92843 in about 25 seconds. I've never seen it take more than a minute (except when it deadlocks, of course). I've really tried to make it faster, but believe me when I say I've spent two days on it and I don't think there's any parts I can remove:
The actual run time will vary across machines, and there's still a bit of randomness involved (both in the deadlines and in the actual SQL operations), but yeah, under a minute for a test like that is the best I can offer for now :) |
I think the issues here are fixed, please reopen if I missed something. |
In light of #18 (comment) - I've adjusted the
pool.Put
check to read:and sure enough, connections with non-reset statements were being put back into the pool.
There's two problems afaict:
stmt.Reset()
is never called fromsqliteutil/exec.go
stmt.Reset()
will not reset if we've already been interruptedsqlite3_reset
, it callsstmt.interrupted
, which callsstmt.conn.interrupted
, which sure does return anSQLITE_INTERRUPT
errorWhat I've done locally to "fix" it is:
stmt.ForceReset()
, which does not check forstmt.interrupted
defer stmt.ForceReset()
at the beginning ofexec()
(lower-case).However, this isn't a great solution, as will become apparent in my next issue...
The text was updated successfully, but these errors were encountered: