-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat: Add ConcurrencyController interface for ARC in exporterhelper #14318
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
base: main
Are you sure you want to change the base?
Conversation
…pentelemetry-collector into controller-interface
…havior unchanged when ARC is disabled
|
@axw @dmitryax @bogdandrutu gentle ping on this PR (#14318). I wanted to check if you could take a look when you have a moment. This introduces the Would appreciate a review on the API shape/placement and the integration points. Happy to iterate quickly on any feedback or adjust/split if needed. Thanks! |
axw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @raghu999!
My main feedback so far is:
- The interface is very narrow, and seems a bit too coupled to ARC. I'd like to see if we can change that into a more general exporter request/sender middleware interface without compromising ARC.
- The minConsumersWithController bit feels off. I'm not convinced we should change the default due to some other setting - seems like that would be surprising. A couple of thoughts:
- Can we for now just have the extension log a warning if the default is set low?
- Would it make sense for the controller to be able to add consumers? Maybe as a separate extension point in asyncQueue, but referencing the same extension?
@axw Thanks for the review — I’ve updated the PR based on your feedback: “Why 200?” / defaults & warnings No-op middleware (avoid nil checks) General middleware interface |
77cbada to
3613de8
Compare
3613de8 to
f2d39d9
Compare
…rt.Equal to assert.GreaterOrEqual
axw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored the ARC-coupled interface into a generic RequestMiddleware / RequestMiddlewareFactory. I explored the WrapSender(... internal/request,sender ...) style, but extensioncapabilities can’t depend on exporterhelper/internal/... types due to Go internal visibility rules and it would also introduce an import cycle. Using Handle(ctx, next func(ctx) error) keeps the interface general and decoupled while letting extensions encapsulate timing/permits/error logic.
The interface doesn't have to live in extensioncapabilities. For example, there's https://github.com/open-telemetry/opentelemetry-collector/tree/main/extension/extensionmiddleware for HTTP and gRPC middleware. I wouldn't recommend adding it in there, just using it as an example. Perhaps we could introduce a new package under https://github.com/open-telemetry/opentelemetry-collector/tree/main/extension/xextension?
Thanks for the review @axw! I've updated the PR to incorporate all suggested changes: Configuration (config.go):
Interface Location:
Ready for a re-review! |
ce09eef to
7466c9e
Compare
Thanks, @axw. I agree moving the interface to exporterhelper/internal and aliasing it in xexporterhelper is the right move here. It cleanly resolves the circular dependency issues caused by xextension needing to reference exporterhelper types. I've applied that change and also refactored queue_sender.go to use the lazy-binding pattern you suggested (storing next as a field and wrapping it in Start). This allowed me to remove the RequestMiddlewareFactory entirely, which significantly simplifies the plumbing. The tests passed locally. Ready for another look. |
|
|
||
| // Start overrides the default Start to resolve the extensions and wrap the sender. | ||
| func (qs *queueSender) Start(ctx context.Context, host component.Host) error { | ||
| mws := make([]requestmiddleware.RequestMiddleware, 0, len(qs.mwIDs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see the requestmiddleware code - seems you missed adding it to your commits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@axw Apologies, yes, looks like I missed adding the requestmiddleware code. Just added, please check. I also incorporated the other review comments (removed the warning logic and the superfluous tests).
db733c3 to
205a167
Compare
axw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Co-authored-by: Andrew Wilkins <[email protected]>
@axw I’d appreciate your validation on the SizerType alias. When I looked at exporterhelper/internal/request/request.go, I noticed the Request interface requires: MergeSplit(ctx context.Context, maxSize int, sizerType SizerType, req Request) ([]Request, error) Since xexporterhelper.Request aliases that interface, any external implementation (including mocks in my extension’s tests) needs to implement MergeSplit. Because SizerType is internal, I couldn’t find a way to write that method signature externally without re-exporting it. Could you let me know if I’m missing a different pattern here? If the alias is undesirable, do you have a preferred way external consumers are expected to satisfy the MergeSplit contract? |
Description
This PR introduces the
ConcurrencyControllerinterface and integrates it into theexporterhelper.Changes:
ConcurrencyControllerinterface.exporterhelperto support dynamic concurrency adjustments.Link to tracking issue
Fixes #14080
Testing
ConcurrencyControllerinterface.exporterhelpertests pass to ensure no regression in current behavior.Documentation