-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: Allow to change net/http.Server base context #16220
Comments
CL https://golang.org/cl/24660 mentions this issue. |
I'm against this change. If you need to setup a context handler you can always have the default mux pass the request a global handler, setup the context, then pass it on to the actual mux. This also let's you specify a cancel context as well. How the mentioned CL and example are used, it would just setup the context to be a bag of values. And the only values you could add to it would be static values; there would be no way to inject a "current" value. |
Hello thank you for the response. The problem with global handler starts if you need to initialize something only once like session store or db (I know its debatable if you want to put your db into context). Before context was moved to stdlib many people including myself was using net/context to eliminate global variables and package.Init() hell. If we use global handler we still need global variables for all things you need to initialize once. |
@gregory-m Please consider the following:
You can also use a type that implements the ServeHTTP method and has a db pool as a field. Then you can setup the context from that as well. |
@kardianos clever and little bit hacky. I don't know what core team think, but I'am good with close this issue, and see what will happen after 1.7 release and context adoption. |
I think with Go 1 an ok application solution is a separate package with the HTTP handling, a private global context variable, and just directly call the global variable methods in your handlers. |
If we were designing net/http from scratch, I would say that ListenAndServe should take a Context argument. But we can't add that now without breaking the Go1 compatibility guarantee, and I don't think it's worth adding a second ListenAndServeWithContext. :/ So a vague +1 to being able to set the context in the Server struct, even if that's not the best place for it. |
@kardianos makes a good point that there are ways to do this as-is. I think I'll close this issue instead for now. I think somebody should wrap up @kardianos's example into a small func or repo somewhere. (I'd take it into https://go4.org/ too) We can revisit this in another release or so, but I imagine we don't add more API for this. |
@bradfitz With @kardianos's solution, you lose the context information associated with the request by net/http. Such as the cancellation support. How would you replicate this in the handler? |
Replace context.Background() with r.Context(). |
If you do that then you lose propagation from whatever background context the user wants to use. |
Either add the values to it or spin up a routine to wait for either ctx to finish in a select. |
It's not always possible to add the values to the context. The necessary key may or may not be accessible to the user. /cc @bradfitz PTAL at my comments here. |
You can merge the two contexts with https://golang.org/pkg/context/#WithCancel and then cancel it after the inner ServerHTTP is done. |
Sorry if I'm being dense here. How do you merge two contexts using WithCancel? |
@quentinmit on my desktop now, I'll try to expand. Example 1: append to context using a function
Example 2: assume your bag of values context is opaque. Unsure when this would actually happen in practice.
Example 3: assume you have values from an external context AND it has a cancel function. This wouldn't be possible with setting a background context.
You could also probably do something fancier by starting a goroutine and waiting on two ctx.Done() in a select, but the above should work. The second example, where you have a bag of opaque values but no deadline seems odd. Could you explain why you have this situation? Examples 1 and 3 seem far more likely. |
Yeah, sorry, you can't merge two contexts' values without implementing a custom Context type. But between that and spinning up a goroutine to wait for one's cancelation or deadline as @kardianos mentioned, I think there are sufficient ways to do this otherwise. It's at least not a priority for me for Go 1.8. I'd like to avoid adding API where possible, especially if it might encourage context misuse, and it's still too early to tell. And the OP's request is easy enough with #16220 (comment) |
FYI, this proposal is going to end up happening via #18997. |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go version go1.7beta2 darwin/amd64
What did you do?
I'am trying to setup my session store and pass it to handlers via http.Request.Context()
What did you expect to see?
Some way to do this.
Like:
What did you see instead?
I can't change base http.Request.Context()
The text was updated successfully, but these errors were encountered: