I’m a little confused if its meant to be used as a singleton. I wanted to call raven.SetUserContext at every http request using a middleware, and hoping that every subsequent raven.CaptureError would send the user data automatically. However, since it’s a singleton, wouldn’t multiple SetUserContext calls overwrite each other, and the subsequent Capture* calls not guaranteed to get the correct user?
You’re right. I’ve wanted to refactor stuff to leverage Context now which is in stdlib for our Context management so it can use COW and be thread safe correctly. Unfortunately, we don’t have dedicated resources for our Go SDK yet. But I’m willing to help guide and review changes around this.
Hmm, I’m not sure what COW means sorry, but how would you go about utilizing Context to help this scenario?
As far as I know, Go does not have the concept of thread local or thread static variables, nor goroutine statics. Context requires every single function to be modified to carry it through every layer. You are not supposed to store Context. Even if we do, I’m not sure that will be useful as we still need to pass around the key to get/set the Context.
What I figured from this implication is that:
- All raven functions need to be changed to accept the Context, which isn’t too different from today where I can pass in the User or Http interfaces directly as part of calling Capture*(), as long as my own code carries through Context everywhere or some other type of my own data structure containing User.
- Whenever I use third party library that doesn’t carry through Context I’m stuck. Sometimes I write code as plug-in to a 3rd party lib, implementing their interfaces. When that code wants to log an error, I won’t have access to Context.
Interesting read on this topic and someone attempted to solve it, but not quite elegantly I have to say.
COW is copy on write, which is what Context does. Generally used to make things thread safe.
But yeah, you’re right that things would need to be modified heavily to support this. Most of the stdlib already does this for us and will happily pass Contexts through. So if we can follow suit and adapt to their pattern, in theory we can do something here.
I’ll admit, I’ve spent hardly any time dealing with this yet, so not 100% confident what’s in my head would work. I only think it will at this point.
Ideally this would be more of an internal implementation and wouldn’t be exposed a lot for the user using the SDK. So you wouldn’t have to keep track of this and our APIs wouldn’t change a ton.