-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[improve][cli] Add client side looping in "pulsar-admin topics analyze-backlog" cli to avoid potential HTTP call timeout #25126
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: master
Are you sure you want to change the base?
Conversation
pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdTopics.java
Show resolved
Hide resolved
| String[] messageIdSplits = mergedResult.getLastMessageId().split(":"); | ||
| MessageIdImpl nextScanMessageId = | ||
| new MessageIdImpl(Long.parseLong(messageIdSplits[0]), Long.parseLong(messageIdSplits[1]) + 1, | ||
| partitionIndex); |
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.
Instead of parsing the message Id String, it would be better to use org.apache.pulsar.client.api.MessageIdAdv interface to get the ledgerId and entryId.
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.
Could you provide me more information, I couldn't find one method that could parse ledgerId:entryId string to a MessageIdAdv instance.
| print("Analyze backlog progress, scanned entries: " + mergedResult.getEntries() | ||
| + ", scan max entries: " + backlogScanMaxEntries); |
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.
It would be useful to print the current value of mergedResult in json format without linefeeds so that the CLI output can be parsed as NDJSON.
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.
There are two ObjectMapper in CliCommand, so we should use the one without pretty printer to print json without linefeeds, and then pass the json string to print() method. Is my understanding correct?
pulsar/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CliCommand.java
Lines 140 to 141 in 85625e0
| private static final ObjectMapper MAPPER = ObjectMapperFactory.create(); | |
| private static final ObjectWriter WRITER = MAPPER.writerWithDefaultPrettyPrinter(); |
pulsar/pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CliCommand.java
Lines 120 to 130 in 85625e0
| <T> void print(T item) { | |
| try { | |
| if (item instanceof String) { | |
| commandSpec.commandLine().getOut().println(item); | |
| } else { | |
| prettyPrint(item); | |
| } | |
| } catch (Exception e) { | |
| throw new RuntimeException(e); | |
| } | |
| } |
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.
yes, there would have to be an option to print out without linefeeds (no pretty printing, line feeds escaped).
| partitionIndex); | ||
| startPosition = Optional.of(nextScanMessageId); | ||
| } | ||
| print(mergedResult); |
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.
output would have to be json format without linefeeds to make the CLI output parseable as NDJSON. The last line in the output would be the final result. Perhaps there could be a command line option to configure whether ndjson should be used since it's not pretty printed.
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.
Perhaps there could be a command line option to configure whether ndjson should be used since it's not pretty printed.
A little bit confused. Does this option only take effect on the final result, or does it also apply to the intermediate results?
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.
A little bit confused. Does this option only take effect on the final result, or does it also apply to the intermediate results?
it would be useful to be able to printout the aggregated result in the loop (in Predicate<AnalyzeSubscriptionBacklogResult> terminatePredicate added in #25127) in ndjson format (json without linefeeds) or json format. The ndjson format would be machine readable so that's the reason to have that option.
| } | ||
|
|
||
| @Test | ||
| public void topicsAnalyzeBacklog() throws Exception { |
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.
A test without mocks, similar to the tests in #25127 would be useful in addition since it would serve as an integration test.
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 haven't found similar examples for reference. Could you provide me some examples.
I don't know how to invoke admin CLI in integration tests and how to receive the outputs(since they are printed to the console output).
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.
Seems we need to handle the test in integration module like CLITest?
Is there a better approach? Running the tests in integration module requires local image building.
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.
Seems we need to handle the test in integration module like
CLITest?Is there a better approach? Running the tests in integration module requires local image building.
Yes it's a bit clumbersome.
To build an image quickly, use this script:
./build/build_java_test_image.sh
That requires setting export PULSAR_TEST_IMAGE_NAME=apachepulsar/java-test-image:latest environment variable so that the apachepulsar/java-test-image:latest docker image is used instead of the default apachepulsar/pulsar-test-latest-version:latest which takes much longer to build.
If you are running the test in IntelliJ, you can edit the default value at
Line 62 in 15daf18
| "apachepulsar/pulsar-test-latest-version:latest"); |
For running integration tests on command line, this is the sequence I have used:
# compile integration test dependencies
mvn -am -pl tests/integration -Dcheckstyle.skip=true -Dlicense.skip=true -Dspotbugs.skip=true -DskipTests install
./build/build_java_test_image.sh
export PULSAR_TEST_IMAGE_NAME=apachepulsar/java-test-image:latest
# run the test
mvn -DintegrationTests -pl tests/integration -DtestRetryCount=0 -DredirectTestOutputToFile=false test \
-Dtest=TestClassNameHere
If you are working on the test alone, you obviously don't have to rebuild the image after each change.
|
@oneby-wang #25127 has been merged |
b48e0eb to
83bdbf1
Compare
| print(getTopics().analyzeSubscriptionBacklog(persistentTopic, subName, startPosition)); | ||
|
|
||
| AnalyzeSubscriptionBacklogResult mergedResult = null; | ||
| while (true) { |
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.
Are you planning to reuse the new API added in #25127 ?
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.
Yes, I'll refactor this PR by reusing the new API added in #25127 and resolve the above comments once I'm back.
I'll re-request review once the refactoring is done.
Fixes #25083
Motivation
Use client-side looping instead of increasing broker settings to avoid potential HTTP call timeout in "pulsar-admin topics analyze-backlog" cli.
Modifications
Add client-side looping, add test.
Verifying this change
Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes
Documentation
docdoc-requireddoc-not-neededdoc-completeMatching PR in forked repository
PR in forked repository: oneby-wang#21