Cherry-pick #19632 to 7.x: Composable ACKer #19742
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cherry-pick of PR #19632 to 7.x branch. Original message:
What does this PR do?
This change replaces the ACK handler functions with a single interface
that makes it easier to combine ACK handlers.
The global ACK handler is removed from the pipeline, requiring Beats to
wrap and compose per input ACK handlers with their own ones.
Review Notes
Although the PR is quite big, the main difference is that the
ACKCount
,ACKEvents
, andACKLastEvents
handlers have been replaced by a single interface (beat.ACKer
). The original ACKer implementations fromlibbeat/publisher/pipeline/acker.go
andlibbeat/publisher/pipeline/client_acker.go
have been movedlibbeat/common/acker
. The former private implementation is now exposed as Helpers for writing and combining ACK handlers. Support for global ACK handlers has been removed. Theacker.Combine
andacker.ConnectionOnly
are the only new additions to the code base.Why is it important?
tl;dr This change is required to integrate the v2 input API.
The global ACK handler support was introduced for filebeat, that did require some support for combine events from multiple inputs before applying state updates. With the introduction of the v2 input API this requirement will go away, as per input type managers are responsible for handling state update and ACKs.
In order to run old and new architecture in parallel, we need to combine ACK handling from input managers, existing input, custom registrar ACKer in filebeat, and event counting support (also via ACK handling) for shutdown. Exposing the interface and providing combinators (acker.Combine) for merging ACK handlers into one helps with the integration.
The v2 Input API gives implementors more flexibility in how to handle event publishing, coordination, and state handling shall be implemented. With the original ACK support the callbacks have been deregistered the moment inputs are stopped automatically. But for cursor based inputs we need to continue handling ACKs, even after the input is gone. The interface and helpers provide greater control over ACK handling after shutdown, which is required for the journald, winlog, and file/log inputs.
Checklist
- [ ] I have made corresponding changes to the documentation- [ ] I have made corresponding change to the default configuration filesCHANGELOG.next.asciidoc
orCHANGELOG-developer.next.asciidoc
.Author's Checklist
How to test this PR locally
ACKer implementations should be handled mostly by unit tests. Still, this change can have great impact and some Beats should be tested to double check that we have not introduced any regressions here.
drop_event
with conditional. Check non-filtered events are publishedRelated issues
Dev Docs:
Calls to
pipeline.ConnectWith
that used to setup an ACK callback need to use the acker helpers. Previously the callbacks have been ignored if the input is shutdown, but not all events have been ACKed yet. For end-to-end ACKers that loose the connection to the source-system on shutdown this behavior can be preserved by usingack.ConnectionOnly(<acker>)
.Instead of directly passing callbacks, the callbacks should be wrapped using some of the utility functions in the libbeat/common/acker package:
ACKCount: func(n int) { ... }
withACKHandler: acker.Counting(func(n int) { ... })
.ACKEvents: func(private []interface{}) { ... }
withACKHandler: acker.EventPrivateReporter(func(_ int, private []interface{}) { ... })
.ACKLastEvent: func(private interface{}) { ... }
withACKHandler: acker.LastEventPrivateReporter(func(_ int, interface{}) { ... })
The
(beat.Pipeline).SetACKHandler
method has been removed.libbeat/common/acker
andlibbeat/publisher/pipetool
provide some helpers to modify and combine ACKers for all newbeat.Client
connections. For example this will use the global and local ACK handler for each event published.The
WithACKer
helper can be used arbitrarily often. ACKers are combined level by level viaacker.Combine
.