Conversation
DeleteTarget only released the cluster lock from inside the branch that removes the target from the runtime map, so a target that exists in the config but not in the runtime map returned without unlocking and without error. The API reported success while the lock stayed held. That is the state a collector is in after a restart: it holds locks for targets it has not recreated yet, and its fresh runtime map is empty. Every such lock became a ghost that a later DELETE against the same config could not clear, because that delete also took the non-running branch. The lock is held against the config rather than the runtime target, so it is now released after the runtime cleanup, on both paths. The close and delete of a running target are unchanged, and an unlock error is still returned. Also drop the target's entry from targetsLockFn. The cancel func was invoked but the map entry stayed, so the target continued to be reported as an assignment after it was deleted.
SubscribeRunE rejected a configuration with no subscriptions and no inputs, failing with "no subscriptions or inputs configuration found". A clustered instance is not required to carry any static config: the loader is the source of targets and subscriptions, and startLoader already handles an empty configuration by waiting to become leader and then polling. The check runs before startLoader is reached, so a deployment whose entire point is to manage targets through the API or a KV store could not start at all, which is what the kubernetes example in the repository describes. Take the loader into account so this is only rejected when there is nothing configured to collect from. An empty loader map still counts as no loader.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
SubscribeRunErejects a configuration with no subscriptions and no inputs:A clustered instance does not have to carry any static configuration. The loader is the source of
targets and subscriptions, and
startLoaderis already written for exactly that case - it no-opswhen no loader is set, waits for the instance to become leader, and then polls.
The problem is ordering. This check runs before
startLoaderis reached, so an instance whose entirepurpose is to have its targets managed through the API or a KV store cannot start at all. The error
names subscriptions and inputs as the only sources, when a loader is a third one.
Change
The loader is taken into account, so this is rejected only when there is genuinely nothing configured
to collect from:
An empty loader map still counts as no loader, so a config with a blank
loader:section behaves asit did before.
Test
TestSubscribeRequiresSubscriptionsInputsOrLoadercovers the four meaningful combinations - loaderonly, loader plus inputs, inputs only, and neither - and pins that an empty loader map does not
count as a loader. That last case is the one that could otherwise turn a typo'd
loader: {}into a silent no-op.A note on the test's scope
The validation sits inside a cobra command and is reached through a chain of
GetX()configreaders, so the test exercises the predicate against a real
config.Configrather than drivingSubscribeRunEend to end. That keeps it a unit test, but it does mean the test and the productioncondition are two expressions of the same rule rather than one calling the other. If a reviewer would
prefer the condition extracted into a small helper that both the command and the test call, that is a
reasonable alternative and I am happy to do it that way instead - the current shape keeps the diff to
one line plus a test.
Verification
go test ./pkg/app/... -count=1go test ./pkg/app/ -run TestSubscribeRequires -count=1go build ./...go vet ./pkg/app/gofmt -lon both filesFixes #787