4 ms·
When reading the title, I was hoping it would mean better abstractions than context for passing around OpenTelemetry info in a golang codebase
by bpicolo 3y ago
When reading the title, I was hoping it would mean better abstractions than context for passing around OpenTelemetry info in a golang codebase
- xyzzy_plugh 3y agoIt's a real shame libraries like OpenTelemetry encourage using the context to pass information around. In my programs I prefer to be explicit. Sadly this breaks so many libraries which also depends on having a magically configured context to function properly. It's thread local storage all over again.
- XorNot 3y agoI like explicit but I don't want to do a whole lot of extra typing either. What I'd really like to see if the type system automatically infer the type of something like the context object implicitly.
- omginternets 3y agoHmm, my editor is able to autocomplete this. Not yours?
- jerf 3y agoI assume you mean that your editor is able to autocomplete that something is a context.Context. I assume what the GP means is to infer a strong type for a struct that has all the data a context has in it. This is much harder, for many reasons. A context that comes in from one path may have a RequestSource in it, but another may not; the resulting type of the function is rather complicated to infer. We prefer not to have two different functions as a result. There's also the problem that such inferences end up strongly tying types across many functions together, such that up in some middleware for your web site you add a new value into the context, and if there was a strong type for that context, that strong type would cascade throughout everything that could someday possibly touch that context. The result is much like checked exceptions in Java. This is perhaps the hardest practical type problem I know. It seems to me to be very related to a similar problem, which is that of trying to strongly type errors. The sort of cross-scope type inference we envision in our heads is extremely unwieldy in practice, if you take the time to try to scope out what that would convert to in a real program with many nested scopes and arbitrarily complicated paths in to those scopes, plus arbitrarily complicated closures being passed around that further impact the types.
- omginternets 3y agoOh right! I had misunderstood.
- jerf 3y agoThe paradox of "thread local storage" is that we both really, really need it, and it blows up if you have it. Contexts are at least a value you can see and manipulate rather than having something attached to your thread, and in particular, can pass across thread boundaries if you need to. One way or another, you end up needing some sort of scope that carries values that can't be strongly typed because the way you're composing those values doesn't work with any known strong type system in practical use. (I've seen some super theoretical ones that can in theory do it but I've never seen them brushed up into something practical and successful.)
- omginternets 3y agoContexts are also immutable where it matters, which helps.
- bpicolo 3y agoProp drilling specific telemetry everywhere in the ecosystem seems much more painful in comparison. C# is pretty neat in having an AsyncLocal[0] that goes beyond what thread locals enable [0]: https://vainolo.com/2022/02/23/storing-context-data-in-c-using-asynclocal/ https://vainolo.com/2022/02/23/storing-context-data-in-c-usi...
- evntdrvn 3y agoyeah it's pretty dang handy :) As long as it's not abused or overused.