-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
[tailsamplingprocessor] Support external decision cache implementations #37035
base: main
Are you sure you want to change the base?
[tailsamplingprocessor] Support external decision cache implementations #37035
Conversation
@Logiraptor please add a changlog entry to |
I'd prefer another approach to this, closer to what we have with the auth extensions, to where we plan to go with policies (#31582), and how we plan to support middlwares: via extensions. Concretely, the config would look like this: extensions:
cacheimpl:
url: ...
max: 1_000
processors:
tailsampling:
cache: cacheimpl To accomplish that, we'd need:
|
@jpkrohling Thanks for the feedback! I'm looking into that now, and I want to make sure I understand since it's my first time contributing to this repo. 🙏 So right now we have this interface: // Cache is a cache using a pcommon.TraceID as the key and any generic type as the value.
type Cache[V any] interface {
// Get returns the value for the given id, and a boolean to indicate whether the key was found.
// If the key is not present, the zero value is returned.
Get(id pcommon.TraceID) (V, bool)
// Put sets the value for a given id
Put(id pcommon.TraceID, v V)
// Delete deletes the value for the given id
Delete(id pcommon.TraceID)
} When I create an extension, are you envisioning the same interface, or something more generic? I believe the key was not made generic intentionally to allow for optimizations in the implementation (using the right side of the id as a key). If the cache should be more generic, then what about something that takes string keys and []byte values? If the cache should not be more generic, then I'm wondering how useful it would be as an extension, since it presumable wouldn't be used by other components. I could be wrong, like I said this is my first contribution here so I'm still learning. What do you think? |
I'll also note that even though the cache is generic on the value type, it's only ever used as |
I think this is the case, and the name should therefore be something like TraceDecisionCache, or something like that. We can reuse it as |
@jpkrohling Got it, ok so working through this I think there's another issue. I don't see how I can maintain type safety through the extension system while also supporting different value types. Specifically, the CreateFunc passed to Similarly, when the tsp tries to get the extension, it will have to type assert the value to some concrete type. So it seems these two pieces of code must implicitly agree on a single concrete type. In that case there's no benefit to using a type parameter. I think the only real solution here is either to forgo type safety using
So now I'm thinking that this cache extension should be a very similar interface with different semantics. e.g. a cache does not guarantee durability between Get / Set whereas a storage does. Thoughts? |
One way I've found which I think could work is like so
Then the components interested in using the cache would essentially get a []byte cache from the system and then can safely convert it (with a codec) into a typed cache. |
Once that codec idea is in place, it would be trivial to add an "easy button" codec like json which can work for most types via reflection. |
@jpkrohling I went ahead and implemented that last idea to see how it looks: main...Logiraptor:opentelemetry-collector-contrib:logiraptor/decision-cache-extension IMO it's OK but unfortunate that every use of the extension needs to pay an encoding cost even if only caching objects in memory. There will be a significant memory usage difference between the original implementation which is generic and this one which has to use What do you think I should do here? |
Description
Adding a feature. This PR adds support for external implementations of the decision cache. This allows the collector (or another service using the processor) to supply an alternative decision cache based on alternative algorithms or external services like memcached without needing to explicitly add support for all possible options in the processor.
It re-uses the existing function option pattern and only exposes two options for now:
WithSampledDecisionCache
andWithNonSampledDecisionCache
. I've avoided exporting other options to avoid bloating the external interface without a concrete use case. The majority of changes are cleanup from the refactoring to moveOption
values into theConfig
struct instead of in a variadic parameter onnewTracesProcessor
.