-
Notifications
You must be signed in to change notification settings - Fork 110
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
Feature/interruptible execution clean2 #796
Feature/interruptible execution clean2 #796
Conversation
|
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 is so great. Stoked about this one.
Leaving a "Comment" rather than "Approve" review as there are quite a few Cpp changes here that I don't feel quite qualified enough to approve. Mostly feedback on the interface to cli conditions from me.
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.
Needs a news bullet too
Looks good from my end and I know users will really be excited about this issue. But I have no ability to review the threaded C++ code, so please wait on @gaborcsardi's review before merging.
R/dbi-driver.R
Outdated
#' prior to the connection being established. See \link{ConnectionAttributes}. | ||
#' @param interruptibleExecution Logical. If `TRUE` calls to SQLExecute and |
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.
Should we mark this as experimental, and to file an issue on GitHub if it's used? I assume we'll eventually take this away once we're confident that it's ok.
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.
Made the note ( exprimental, please bring issues to github ) in the NEWS bullet. Let me know if I should mention it elsewhere as well.
@detule @simonpcouch Some quick comments wrt the new argument and having a (not so) secret option instead. I think an option or an env var is much friendlier for the users than the new argument.
|
@detule A quick question about concurrency and resources. If there is an interrupt, then And after an interrupt, the main thread invalidates the DB handle that the async thread is using? If that's the case, are the ODBC drivers prepared for this? |
Not doing this myself in case @detule has local changes, but this PR should pass CI with changes merged from |
HI @gaborcsardi Appreciate you taking a look.
|
Also: fix some indentation, and snaps.
5f8bac1
to
c340595
Compare
Thanks @simonpcouch - rebased on top of |
I don't see where that happens, probably in In any case, this looks pretty good then. The only concern I have is that you need to install the dev MariaDB drivers to make ODBC run reliably. I would think that many ODBC users are stuck on older Linux systems, so we could potentially break their projects. So maybe you could make this feature opt-in for now? And make it the default in the next release? |
Yes, both
Thanks @gaborcsardi . Appreciate you taking a look. On |
You can make a much more informed decision than me. In general I tend to be conservative in these kind of issues, especially with packages that may be used on older systems, like odbc. You can also make the default depend on whether the session is interactive or not. I would think that interruption is much less important in non-interactive sessions, where an interruption just kills the process, because there are already ways to kill the process. So you could turn it on in interactive sessions only. |
Done - thanks, that's a great suggestion. |
Merge branch 'main' into detule-feature/interruptible_execution_clean2 # Conflicts: # tests/testthat/_snaps/utils.md
(I cannot express sufficiently how much I've wanted this and never knew to ask for it.) |
Hi All:
Please consider adding this feature - the ability to "Ctrl-C" past a long running query. For example in SQL Server
Some notes - i feel like I am being wordy below but I am sure I still left quite a bit out:
Design: Created a
run_interruptible
wrapper that takes two arguments: a function to be executed away from the main thread, and a cleanup function to be invoked once the signal is caught on the main thread. Perhaps this is an overkill but I did this with an eye that maybe some day we may need to be able to interrupt other calls from theodbc
API, not justSQLExecute
. We can then just re-use the wrapper.Design: Used
std::async
rather thanstd::thread
: I personally am a little biased towardsstd::async
but mostly based on semantics. I know there's quite a bit left up to the implementation but at this point it's been around for long enough that I think there should be little in the way of surprises. I've witnessed some passionate thread-vs-async discussions before but I think it's mostly a matter of style. If folks feel strongly one way or another, happy to change it.Design: Signal handling ( away from Windows ) - used the
pthread
API to make sure the SIGINT signal is delivered to the main thread. This is pretty idiosyncratic, but i've seen issues where depending on the implementation, a signal can end up with the wrong thread.Opt-out: Struggled with this for a bit. I am not a fan of
dbConnect
accruing yet more arguments. At the same time also not in love with introducing some sort of a secret option ---getOption(.odbc.interruptible.exec)
--- or somesuch. There is anattributes
arguments todbConnect
but when we introduced it, I think we envisionedODBC
/API connection arguments. So - hated myself a little bit for it - but ended up writing in a new argument todbConnect
.Testing: Pipelines are (hopefully) passing on both windows and linux and that's a good sign. Beyond that, on my linux box, I tested DB2, Oracle, Terradata, Databricks and did not see any issues. Note, the
WAITFOR
style queries are not always interruptible. For example onsnowflake
, interrupting the equivalentSELECT system$wait(10)
won't save you any time since theSQLCancel
call blocks on the main thread after catching the interrupt. However, testing an actual long running execution I saw better behavior.dbSend(Get)Query(conn, NA_character_)
( part ofDBItest::send(get)_query_non_string
)dbSendStatement(conn, NA_character_)
( part ofDBItest::send_statement_non_string
)dbExecute(conn, NA_character_)
( part ofDBItest::execute_non_string
)Note, all remaining (~3.5K)
DBItest
tests pass with both drivers just fine. Spent quite a bit of time comparing odbc traces to no avail, and thought it's something so idiosyncratic ( and fixed in their newer drivers to boot ) that it should probably not hold this feature back. Options to ignore were to use newer driver, or to add the tests to the "skip" list fordriver-mysql
.Appreciate any feedback - and thanks for taking a look!