3 ms·
I thought Context was also used to partially solve the "middleware" problem in http servers. Ex. I have an authorization middleware that takes the http request
by nemothekid 9y ago
I thought Context was also used to partially solve the "middleware" problem in http servers. Ex. I have an authorization middleware that takes the http request parameters and returns an authorization object that is available to request handlers.
Way back when, Martini solved this problem using reflection (which was met with vitriol). Other packages solved this with their own handrolled context object (which was always a map[string]interface{}). I personally always liked how Martini handled it (you got to "keep" your types), but understandably it included way too much magic.
- andrewstuart2 9y agoThe response to Martini always confused me. The language and community (at first, anyway) was all about terse identifiers, type inference, interface inference, etc. But then, e.g. with the continual repetition of `if err != nil {}`, or the "just use stdlib" approach to HTTP, it injects a lot of ceremonial verbosity back into the ecosystem. It's not the verbosity that bothers me. It's the arbitrary "verbosity is bad/verbosity is good" choices that have emerged over time.
- adrianratnapala 9y agoGo is consistently anti-magic, but not particularly terse (although the last time I wrote a Go program next to an equivalent C++ program, it was about 20% shorter). Instead its syntax strives for whatever the hell Rob Pike means by "lightness". Roughly, languages like Java add length by long identifiers and numerous modifiers to convey that something belongs to particular semantic category that behaves in a particular way. Go adds length by having fewers such categories and forcing you to explicitly code up the behaviour. Short identifiers (and proper use of scoping!) are orthognal to this, except insofar as they reduce the pain.
- andrewstuart2 9y agoI guess I'm thinking mostly about the talk Rob Pike gave called "public static void" [1], where he probably describes pretty well what "lightness" means to him, or at least what it meant to him 7 years ago. It seems largely about verbosity. [1] https://www.youtube.com/watch?v=5kj5ApnhPAE https://www.youtube.com/watch?v=5kj5ApnhPAE
- adrianratnapala 9y agoCan you explain how reflection helps here? Are you saying that people still pass tracing objects around, except they don't have to be context.Context? That's nice, but it doesn't sovle the fact that the auther (rightly!) doesn't want to add extra complication to interfaces like io.Reader
- nemothekid 9y agoReflection, the way Martini used it, was for dependency injection. So in our imaginary Go language, the io.Reader interface could be satisfied by either of two functions: Read([]byte) Read(context.Context, []byte) In a way reflection let you do operator overloading, so in your case you could just call a.Read(p) and others could a.Read(ctx, p). In Martini's case, if you wanted your handler to be cognizant of a cancellable context, you would just add the context parameter.
- camus2 9y agoNo context does 2 things : - send signals by exposing a channel - serves as a bag of values (the infamous .Values method ). Context was invented because Go developers kept writing leaky servers as they were referencing *http.Request outside an http.Handler (for session management for instance) . If you do that, you need to be able to signal that the request treatment is done or you will have a memory leak. I guess they added .Values(interface{})interface{} because they could.