-
Notifications
You must be signed in to change notification settings - Fork 373
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
Add new Context parameter #352
Add new Context parameter #352
Conversation
Couple of problems I just noticed with the build. (1) The "context" package was added with Go 1.7 so adding it to the API would break compatibility with Go 1.6. Is that an issue? I guess I could copy it's definition into gorp, but that seems like it would break going forward. (2) The Context API being added to db.Sql wasn't added until I think Go 1.8. I changed it so it will degrade gracefully to not passing on the context in earlier versions, but that will make the test I added fail unless I can exclude that test for earlier versions. |
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.
Thanks for picking up that context issue!
Looks good to me -- but I, of course, can't help with the open questions. No idea what compatibility gorp wants to provide.
gorp_test.go
Outdated
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
|
||
defer time.AfterFunc(100 * time.Millisecond, cancel).Stop() |
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.
I suppose you did that on purpose, just wanted to point out that this is equivalent to:
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
gorp_test.go
Outdated
@@ -2360,6 +2361,31 @@ func TestPrepare(t *testing.T) { | |||
} | |||
} | |||
|
|||
func TestWithCanceledContext(t *testing.T) { |
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.
(2) The Context API being added to db.Sql wasn't added until I think Go 1.8. [...] but that will make the test I added fail unless I can exclude that test for earlier versions.
If you'd put that into its own file, you would be able to add // +build !go1.7
, I believe? To make these tests not run on 1.7? (not entirely sure if it works like that, though)
!go1.7 would make it only run on 1.6 and earlier. it should be +build
go1.8. Other than that, yes - anything that requires 1.8 should be gated
on build tags in separate files.
I think it's somewhere in the readme that we aim to support the two most
recent go versions. If I'm wrong about it being in the readme, well... I
still think supporting the two most recent versions is plenty.
…On Aug 31, 2017 00:42, "Stephan Renatus" ***@***.***> wrote:
***@***.**** approved this pull request.
Thanks for picking up that context issue!
Looks good to me -- but I, of course, can't help with the open questions.
No idea what compatibility gorp wants to provide.
------------------------------
In gorp_test.go
<#352 (comment)>:
> @@ -2360,6 +2361,31 @@ func TestPrepare(t *testing.T) {
}
}
+func TestWithCanceledContext(t *testing.T) {
+ if _, driver := dialectAndDriver(); driver != "mysql" {
+ t.Skip("Cancellation is not yet supported by all drivers. Known to be supported by mysql")
+ }
+
+ dbmap := initDbMap()
+ defer dropAndClose(dbmap)
+
+ ctx, cancel := context.WithCancel(context.Background())
+
+ defer time.AfterFunc(100 * time.Millisecond, cancel).Stop()
I suppose you did that on purpose, just wanted to point out that this is
equivalent to:
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)defer cancel()
------------------------------
In gorp_test.go
<#352 (comment)>:
> @@ -2360,6 +2361,31 @@ func TestPrepare(t *testing.T) {
}
}
+func TestWithCanceledContext(t *testing.T) {
(2) The Context API being added to db.Sql wasn't added until I think Go
1.8. [...] but that will make the test I added fail unless I can exclude
that test for earlier versions.
If you'd put that into its own file, you would be able to add // +build
!go1.7, I believe? To make these tests not run on 1.7? (not entirely sure
if it works like that, though)
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#352 (review)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AA-QBGNy7lnyVAm_GE5lh3n1RYmLx43rks5sdlXMgaJpZM4PITIB>
.
|
Hi @MatthewDolan I think you need to add support in a few more places. QueryRow -> QueryRowContext, Query -> QueryContext, Prepare -> PrepareContext, and pretty much any other time there is an alternative Context function call with *sql.DB. |
@bryanpaluch Oh you are totally right. Let me take another look. |
@bryanpaluch Thanks. I updated the PR to add the other calls. Build is passing for 1.7, 1.8, and 1.9. |
I'll review this weekend. I'm blocking out something on my schedule. |
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.
Looks good for the most part, although I'd really like to see other database drivers tested. At least pq
, since it seems like cancellation is tested there, and postgres is the database I use for all of my projects.
I'd say remove the check for mysql
, see if it fails in CI, and only exclude drivers if they're failing in CI. If postgres is failing in CI, I'd like to dig in to why that is before excluding it from the test. When things don't work in postgres, it's usually not because postgres is wrong.
gorp_go18_test.go
Outdated
) | ||
|
||
func TestWithCanceledContext(t *testing.T) { | ||
if _, driver := dialectAndDriver(); driver != "mysql" { |
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.
I would really like to have a blacklist of drivers that don't support it, rather than a whitelist of drivers that do. If you're unsure, assume there is support - if it's not failing in travis, we'll deal with it when it becomes a problem.
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.
Good call. It seems like mymysql is the only driver that has not added support (I filed it as an issue ziutek/mymysql#138).
Ran into one other problem though. Some sql dialects (namely sqlite) don't support native sleep calls. I checked the test for the sqlite driver and it looks like they have an attempt at testing a canceled context (https://github.com/mattn/go-sqlite3/blob/master/sqlite3_go18_test.go#L113), but I don't think it's as clean as sleep. I just excluded the languages that don't support sleep for now.
@nelsam Just in-case you missed my comment inline, I added an exclusion list instead of an inclusion list like you suggested. Let me know if there is anything else I need to update. Thanks for taking a look. |
Yep, I'll check on it soon. I've had a busy couple of days. |
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.
Apologies for taking so long - I very seldom get a chance to review these things during the week, so I mostly have to wait for the weekend.
I'd rather not bump gorp
's major version if we can help it. We can chat about other options, but putting a SleepDialect
interface in the gorp_test
package and using type assertions seems reasonable to me.
gorp_go18_test.go
Outdated
func TestWithCanceledContext(t *testing.T) { | ||
dialect, driver := dialectAndDriver() | ||
if unsupportedDrivers[driver] { | ||
t.Skip("Cancellation is not yet supported by all drivers. Not known to be unsupported in %s.", driver) |
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.
I think this should read Known to be unsupported
or Not known to be supported
, rather than Not known to be unsupported
.
dialect.go
Outdated
@@ -49,6 +51,9 @@ type Dialect interface { | |||
// string to truncate tables | |||
TruncateClause() string | |||
|
|||
// string to sleep for d duration | |||
SleepClause(d time.Duration) string |
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 a breaking change and will force a v3
of gorp
, since some gorp
users may have implemented custom Dialect
types. Can we instead add a new interface type, say SleepDialect
, such that:
type SleepDialect interface {
SleepClause(time.Duration) string
}
And then remove the SleepClause
methods on dialects that don't have a sleep clause?
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.
In addition, since this method is only used by tests, can we move the SleepDialect
interface to the test package? If it's in gorp
's main package, then users expect that implementing SleepDialect
gives them something from gorp
, rather than gorp
's tests.
dialect_oracle.go
Outdated
@@ -93,6 +94,10 @@ func (d OracleDialect) TruncateClause() string { | |||
return "truncate" | |||
} | |||
|
|||
func (d OracleDialect) SleepClause(s time.Duration) string { | |||
return "" | |||
} |
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.
If we were to use a separate SleepDialect
, you could just skip implementing this method.
dialect_sqlite.go
Outdated
@@ -88,6 +89,10 @@ func (d SqliteDialect) TruncateClause() string { | |||
return "delete from" | |||
} | |||
|
|||
func (d SqliteDialect) SleepClause(s time.Duration) string { | |||
return "" | |||
} |
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.
Same here as with the OracleDialect - you wouldn't have to implement this method here.
dialect_sqlserver.go
Outdated
@@ -103,6 +104,10 @@ func (d SqlServerDialect) TruncateClause() string { | |||
return "truncate table" | |||
} | |||
|
|||
func (d SqlServerDialect) SleepClause(s time.Duration) string { | |||
return "" | |||
} |
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.
Same as with Oracle and Sqlite
gorp_go18_test.go
Outdated
t.Skip("Cancellation is not yet supported by all drivers. Not known to be unsupported in %s.", driver) | ||
} | ||
|
||
if dialect.SleepClause(time.Second) == "" { |
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.
If we used a SleepDialect
, this would change to:
sleeper, ok := dialect.(SleepDialect)
if !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.
LGTM
@MatthewDolan anything you want to add before merge? Otherwise, I can merge now. |
Everything looks good to me. Feel free to merge. Thanks for looking through this. |
Thanks for the submission! I'm trying to be more active with |
This tries to introduce the ability to provide a context, while keeping the API surface intact, and not changing every single method signature. It is modelled slightly after how gorp had done the same thing three years ago: go-gorp/gorp#352 Signed-off-by: Stephan Renatus <[email protected]>
This tries to introduce the ability to provide a context, while keeping the API surface intact, and not changing every single method signature. It is modelled slightly after how gorp had done the same thing three years ago: go-gorp/gorp#352 Signed-off-by: Stephan Renatus <[email protected]>
This tries to introduce the ability to provide a context, while keeping the API surface intact, and not changing every single method signature. It is modelled slightly after how gorp had done the same thing three years ago: go-gorp/gorp#352 Signed-off-by: Stephan Renatus <[email protected]>
Potential solution to #344