Skip to content
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

Proposal: Allowing context to be used with client-go #1166

Closed

Conversation

maleck13
Copy link

@maleck13 maleck13 commented Oct 9, 2017

This is a first pass at a set of changes aimed at allowing consumers of client-go to leverage functionality offered by the context package in the std lib. It is in response to the following issue:
kubernetes/kubernetes#46503

To the reviewers:
This is the first proposal I have done for Kubernetes so any feedback and guidance would be appreciated, I am not really sure of the process after creating the proposal.

@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Oct 9, 2017
@jbeda
Copy link
Contributor

jbeda commented Oct 9, 2017

It would be best for someone from API Machinery to comment here.

@kubernetes/sig-api-machinery-pr-reviews

@k8s-ci-robot k8s-ci-robot added the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label Oct 9, 2017
@jbeda jbeda removed their assignment Oct 9, 2017

// WithContext allows you to set a context that will be used by the underlying http request
func (c *pods) WithContext(ctx context.Context) PodInterface {
c.ctx = ctx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithContext should not mutate, but has to create a shallow copy first.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain a little more, do you mean before the assignment on line 60 happens? My understanding is ctx is being passed by value into this method and so is a shallow copy or am I misunderstanding?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I meant a shallow copy of c *pods.


**Concerns**

This is very clearly a breaking change that would likely require extensive changes to both tests and implementation code throughout the impacted code bases.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't care much about everything in k8s.io/kubernetes. It's a one-time cleanup to adapt using context.ToDo().

Passing a context through where it makes sense would be a bigger change, but that's not dependent on which of your solution we choose.

It's also a breaking change for our published client-go. We actually had similar changes in 1.6 with GetOptions and ListOptions. It might be tedious for our 3rdparty users to fix their code. But at least the breakage and fix is obvious and easy to repair.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that is it is relatively easy to fix. Also clearly announces context support in the client. With the none breaking change, a consumer would need to discover that context support was now available.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the other hand, this approach would guarantee that we update all call sites. The other we could silently miss them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

silently missing call site updates seems bad

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be more concerned with third-parties scrambling to fix their build and misusing context without. If we silent'y failed back to context.ToDo() people could add context on their own initiative.

@ggaaooppeenngg
Copy link

Any further work?

@maleck13
Copy link
Author

maleck13 commented Nov 2, 2017

@ggaaooppeenngg I have not put any additional work in yet. Not entirely sure what the next steps would be

@smarterclayton
Copy link
Contributor

smarterclayton commented Nov 5, 2017 via email

@maleck13
Copy link
Author

maleck13 commented Nov 6, 2017

@sttts You mentioned a similar change when adding the GetOptions and ListOptions are you aware of how this change was communicated?

@smarterclayton pkgs in the stdlib are making use of the context pkg, but I am also unfamiliar with the wider uptake in community pkgs.

@sttts
Copy link
Contributor

sttts commented Nov 6, 2017

You mentioned a similar change when adding the GetOptions and ListOptions are you aware of how this change was communicated?

As most of our breaking changes not very well https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md#v300. But at least it's pretty obvious for every 3rdparty what changed and how to fix it. I worry more about changes which have a less clear local fix. Contexts will belong to the former.

@maleck13
Copy link
Author

maleck13 commented Nov 6, 2017

Ok so is the next step here then to do an actual implementation or is there more that needs doing on the proposal?

@maleck13
Copy link
Author

I am hoping to start on an implementation of this early in the new year after the holiday period.

@maleck13
Copy link
Author

@sttts should we consider adding ctx support to the client-gen tool also?

@sttts
Copy link
Contributor

sttts commented Dec 11, 2017

should we consider adding ctx support to the client-gen tool also?

We have to, don't we?

@maleck13
Copy link
Author

@sttts Yes of course we do, ignore the previous comment

@maleck13 maleck13 changed the title Proposal: First pass at allowing context to be used with client-go Proposal: Allowing context to be used with client-go Jan 5, 2018
@maleck13
Copy link
Author

started looking at the implementation for this, new to the client generator so it may take a little while

@lavalamp
Copy link
Member

cc @yliaog

@maleck13
Copy link
Author

@sttts I believe I have the changes in the gen tools done. I would like to create a WIP pr to get feedback, unless there is a reason not to, I will create the WIP pr in the morning.

@sttts
Copy link
Contributor

sttts commented Jan 23, 2018

I will create the WIP pr in the morning.

Sure, assign it to me.

k8s-github-robot pushed a commit to kubernetes/kubernetes that referenced this pull request May 19, 2018
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: #59287 #58532 #815 kubernetes/community#1166 #58677 #57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts
k8s-publishing-bot added a commit to kubernetes/apimachinery that referenced this pull request May 19, 2018
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: kubernetes/kubernetes#59287 kubernetes/kubernetes#58532 kubernetes/kubernetes#815 kubernetes/community#1166 kubernetes/kubernetes#58677 kubernetes/kubernetes#57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts

Kubernetes-commit: ddf551c24b7d88454f8332ce6855e53281440958
k8s-publishing-bot added a commit to kubernetes/client-go that referenced this pull request May 19, 2018
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: kubernetes/kubernetes#59287 kubernetes/kubernetes#58532 kubernetes/kubernetes#815 kubernetes/community#1166 kubernetes/kubernetes#58677 kubernetes/kubernetes#57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts

Kubernetes-commit: ddf551c24b7d88454f8332ce6855e53281440958
k8s-publishing-bot added a commit to kubernetes/apiserver that referenced this pull request May 19, 2018
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: kubernetes/kubernetes#59287 kubernetes/kubernetes#58532 kubernetes/kubernetes#815 kubernetes/community#1166 kubernetes/kubernetes#58677 kubernetes/kubernetes#57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts

Kubernetes-commit: ddf551c24b7d88454f8332ce6855e53281440958
k8s-publishing-bot added a commit to kubernetes/kube-aggregator that referenced this pull request May 19, 2018
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: kubernetes/kubernetes#59287 kubernetes/kubernetes#58532 kubernetes/kubernetes#815 kubernetes/community#1166 kubernetes/kubernetes#58677 kubernetes/kubernetes#57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts

Kubernetes-commit: ddf551c24b7d88454f8332ce6855e53281440958
@fejta-bot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label May 29, 2018
@smarterclayton
Copy link
Contributor

smarterclayton commented May 30, 2018 via email

@k8s-ci-robot k8s-ci-robot added the lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. label May 30, 2018
@smarterclayton
Copy link
Contributor

/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot removed the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label May 30, 2018
@cceckman
Copy link

cceckman commented Jul 9, 2018

Gentle ping. Is this waiting on anything? (Attention from reviewers?)

@sttts
Copy link
Contributor

sttts commented Jul 10, 2018

We decided in the sig-api-machinery meeting to go forward with a hard one-time signature change. PRs are in the works right now.

```


HTTP Tracing and cancellation are also likely useful when using ```informers``` and ```listers```, as these also use the client interfaces backwards compatibility can be maintained by adding a new set of constructors for adding a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cancellation via deadline or timeout in a context would not work well with a single context provided to a long-lived lister/informer. similarly, trace ids are typically per request, not long-lived. I don't think a single context object for a lister/informer is what we want.

@liggitt
Copy link
Member

liggitt commented Aug 9, 2018

I'm in favor of this, other than the lister/informer bits

Resource("pods").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Context(ctx).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this line meant to be: Context(c.ctx) ?

Resource("pods").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Context(c.ctx).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this line meant to be: Context(ctx)?


These change would impact on every API. Although the changes required would be many, the simplest approach to maintaining current behavior would be to pass ```context.TODO()```.

For the ```listers``` and ```informers``` the change outlined above (adding new constructors) would still allow a context to be passed through to client functions doing the work.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense in the context of listers and informers to specify a context constructor function?

Some sample use cases for context like tracing and deadlines, won't make much sense to set once per informer or lister, but would make more sense to create a new one every time its needed.

Trace id are commonly set per request and the only thing a deadline set at the construction of the informer or lister would do is limit the time your program can get resources from the api.


**Concerns**

This is very clearly a breaking change that would likely require extensive changes to both tests and implementation code throughout the impacted code bases.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be more concerned with third-parties scrambling to fix their build and misusing context without. If we silent'y failed back to context.ToDo() people could add context on their own initiative.

@aanm
Copy link

aanm commented Oct 7, 2018

We decided in the sig-api-machinery meeting to go forward with a hard one-time signature change. PRs are in the works right now.

@sttts Any news with regarding this?

@hypnoce
Copy link

hypnoce commented Jun 5, 2019

This proposal would be a great help for my use case. Currently writing a small service that calls the kubernetes API server. To workaround the problem, I have to create a new kubernetes client with a custom transport every time there is an incoming request.
While it's possible to optimize memory allocation by only creating the client for the needed api group (corev1, extensionv1...), the code still allocates a bunch of resource.

@liggitt
Copy link
Member

liggitt commented Nov 6, 2019

This should move to https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery in KEP form to make progress.

@gkarthiks
Copy link

hi @maleck13 Since we have a KEP process, can we please merge this soon or close this and create a KEP?

@liggitt
Copy link
Member

liggitt commented Feb 3, 2020

Moved to kubernetes/enhancements#1503

@liggitt
Copy link
Member

liggitt commented Feb 3, 2020

/close

@k8s-ci-robot
Copy link
Contributor

@liggitt: Closed this PR.

In response to this:

/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

akhilerm pushed a commit to akhilerm/apimachinery that referenced this pull request Sep 20, 2022
Automatic merge from submit-queue (batch tested with PRs 60012, 63692, 63977, 63960, 64008). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Use Dial with context

**What this PR does / why we need it**:
`net/http/Transport.Dial` field is deprecated:
```go
// DialContext specifies the dial function for creating unencrypted TCP connections.
// If DialContext is nil (and the deprecated Dial below is also nil),
// then the transport dials using package net.
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

// Dial specifies the dial function for creating unencrypted TCP connections.
//
// Deprecated: Use DialContext instead, which allows the transport
// to cancel dials as soon as they are no longer needed.
// If both are set, DialContext takes priority.
Dial func(network, addr string) (net.Conn, error)
```
This PR switches all `Dial` usages to `DialContext`. Fixes #63455.

**Special notes for your reviewer**:
Also related: kubernetes/kubernetes#59287 kubernetes/kubernetes#58532 kubernetes/kubernetes#815 kubernetes/community#1166 kubernetes/kubernetes#58677 kubernetes/kubernetes#57932

**Release note**:
```release-note
HTTP transport now uses `context.Context` to cancel dial operations. k8s.io/client-go/transport/Config struct has been updated to accept a function with a `context.Context` parameter. This is a breaking change if you use this field in your code.
```
/sig api-machinery
/kind enhancement
/cc @sttts

Kubernetes-commit: ddf551c24b7d88454f8332ce6855e53281440958
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/design Categorizes issue or PR as related to design. lifecycle/frozen Indicates that an issue or PR should not be auto-closed due to staleness. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet