Skip to content
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

[fix][broker] Gracefully shutdown does not work with admin cli in standalone #20709

Merged
merged 18 commits into from
Jul 26, 2023
Merged

[fix][broker] Gracefully shutdown does not work with admin cli in standalone #20709

merged 18 commits into from
Jul 26, 2023

Conversation

JooHyukKim
Copy link
Contributor

@JooHyukKim JooHyukKim commented Jul 3, 2023

Fixes : #20617

Motivation

Currently, clients' shutdown API does not behave consistently in sense that asynchronicity is not handled explicitly. So issue #20617 happens.

This PR will allow clients know that shutdown is actually triggered.

Modifications

  • Synchronize call to POST /shutdown on client side
  • Asynchronize explicitly pulsar().closeAsync() invocation

Verifying this change

  • Make sure that the change passes the CI checks.

Does this pull request potentially affect one of the following parts:

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository: https://github.com/JooHyukKim/pulsar/pull/17

Note

Here is link to the original PR, that ended up in messed up state wrt merge.

@github-actions github-actions bot added the doc-required Your PR changes impact docs and you will update later. label Jul 3, 2023
@JooHyukKim JooHyukKim changed the title [improve][admin] Gracefully shutdown does not work with admin cli in standalone [fix][broker] Gracefully shutdown does not work with admin cli in standalone Jul 4, 2023
Copy link
Contributor

@Technoboy- Technoboy- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple way to fix this is to wait the future.

getAdmin().brokers().shutDownBrokerGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic).join();

@Technoboy- Technoboy- added this to the 3.1.0 milestone Jul 4, 2023
@Technoboy- Technoboy- added area/cli doc-not-needed Your PR changes do not impact docs and removed doc-required Your PR changes impact docs and you will update later. labels Jul 4, 2023
@github-actions github-actions bot added doc-required Your PR changes impact docs and you will update later. and removed doc-not-needed Your PR changes do not impact docs labels Jul 4, 2023
@JooHyukKim JooHyukKim requested a review from Technoboy- July 4, 2023 04:26
) {
validateSuperUserAccess();
doShutDownBrokerGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic);
doShutDownBrokerGracefullyAsync(maxConcurrentUnloadPerSec, forcedTerminateTopic, asyncResponse);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doShutDownBrokerGracefullyAsync().thenAccept(__ -> asyncResponse.resume(Response.noContent().build()));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay. I see where this is headed. Thank you! @Technoboy-

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And need to add exceptionally

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we can use validateSuperUserAccessAsync

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Technoboy- thank you so much for the guidance. I should've thought of this solution earlier, before implementing this in more than 3 possible ways 🥲.

Done applying your review, though it seems clean and ready atm, I will see if there is anything else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems can't give a response after close, see:#14114 (comment)

@JooHyukKim JooHyukKim requested a review from Technoboy- July 4, 2023 09:41
getAdmin().brokers().shutDownBrokerGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic);
System.out.println("Successfully trigger broker shutdown gracefully");
getAdmin().brokers().shutDownBrokerGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic).join();
System.out.println("Successfully shutdown broker gracefully");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find that we have many async calls in the cli, we'd better add a sync call the CmdBase:

protected long getReadTimeoutMs() {
        PulsarAdmin pulsarAdmin = getAdmin();
        if (pulsarAdmin instanceof PulsarAdminImpl) {
            return ((PulsarAdminImpl) pulsarAdmin).getClientConfigData().getReadTimeoutMs();
        }
        return 60000;
    }

    protected <T> T sync(Supplier<CompletableFuture<T>> executor) throws PulsarAdminException {
        try {
            return executor.get().get(getReadTimeoutMs(), TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new PulsarAdminException(e);
        } catch (TimeoutException e) {
            throw new PulsarAdminException.TimeoutException(e);
        } catch (ExecutionException e) {
            throw PulsarAdminException.wrap(getApiException(e.getCause()));
        } catch (Exception e) {
            throw PulsarAdminException.wrap(getApiException(e));
        }
    }

And change this sync:

sync(() -> getAdmin().brokers().shutDownBrokerGracefully(maxConcurrentUnloadPerSec, forcedTerminateTopic));
            System.out.println("Successfully trigger broker shutdown gracefully");

What's your idea ? @codelipenghui @poorbarcode @mattisonchao @coderzc

Copy link
Contributor Author

@JooHyukKim JooHyukKim Jul 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Cmd classes are better off staying simple (not include sync/async) and users are also better off controlling only through CLI params.

EDITED And in this case maybe we can add parameter like --wait-for-completion, as suggested previously by @315157973 in #20651 (comment)

@JooHyukKim JooHyukKim requested a review from Technoboy- July 8, 2023 09:04
Comment on lines 552 to 556
.thenCompose(__ -> doShutDownBrokerGracefullyAsync(maxConcurrentUnloadPerSec, forcedTerminateTopic))
.thenAccept(__ -> {
LOG.info("[{}] Successfully shutdown broker gracefully", clientAppId());
asyncResponse.resume(Response.noContent().build());
})
Copy link
Contributor

@labuladong labuladong Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doShutDownBrokerGracefullyAsync method will close the web service. After the web service is closed, can asyncResponse.resume(Response.noContent().build()); work? I think we can resume the response first, tell the admin CLI that the shutdown process has been triggered, finish the HTTP request. Then call doShutDownBrokerGracefullyAsync to do the shutdown. What do you think?

Copy link
Contributor Author

@JooHyukKim JooHyukKim Jul 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think?

There is similar discussion above #20709 (comment) regarding synchronicity that we need to agree upon. Shall we discuss there also, and keep idea in one place?

Copy link
Contributor

@labuladong labuladong Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think my question is similar to #20709 (comment). I mean, if we run doShutDownBrokerGracefullyAsync first, then run asyncResponse.resume(Response.noContent().build());, is that OK? In doShutDownBrokerGracefullyAsync method, the admin web service will be shut down, can asyncResponse.resume succeed when the web service has shut down?

I'm not sure if my guess is accurate, but I remember encountering a similar situation before. I suggest run asyncResponse.resume(Response.noContent().build()); first, then run doShutDownBrokerGracefullyAsync, to ensure the request can be finished in admin CLI.

@JooHyukKim JooHyukKim requested a review from coderzc July 11, 2023 06:02
Copy link
Contributor

@Technoboy- Technoboy- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@labuladong
Copy link
Contributor

/pulsarbot rerun-failure-checks

@JooHyukKim
Copy link
Contributor Author

/pulsarbot rerun-failure-checks

@labuladong Thank you for the rerun 👍🏻. The failure (Docker iamge build) has been fixed in #20831 , so the CI should work now.

@JooHyukKim JooHyukKim requested a review from Technoboy- July 25, 2023 10:54
Comment on lines +46 to +49
/**
* Default read timeout in milliseconds.
* Used if not found from configuration data in {@link #getReadTimeoutMs()}
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JooHyukKim this PR is labeled with doc-required, and explanations have been added to API code files. Does it mean that the doc has been already added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don't think doc-required label is applicable anymore. The label must have been along the way.

WDYT, @Anonymitaet ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there is no public API change, we might just move to doc-not-needed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@Anonymitaet Anonymitaet added doc-not-needed Your PR changes do not impact docs and removed doc-required Your PR changes impact docs and you will update later. labels Aug 8, 2023
Technoboy- pushed a commit that referenced this pull request Aug 17, 2023
…ndalone (#20709)

Fixes : #20617

### Motivation

Currently, clients' shutdown API does not behave consistently in sense that asynchronicity is not handled explicitly. So issue #20617 happens.

This PR will allow clients know that shutdown is actually triggered.

### Modifications

- Synchronize call to `POST /shutdown` on client side
- Asynchronize explicitly `pulsar().closeAsync()` invocation
@JooHyukKim JooHyukKim deleted the 20617-fix-CLEAN branch August 23, 2023 12:18
liangyepianzhou pushed a commit that referenced this pull request Aug 25, 2023
…ndalone (#20709)

Fixes : #20617

Currently, clients' shutdown API does not behave consistently in sense that asynchronicity is not handled explicitly. So issue #20617 happens.

This PR will allow clients know that shutdown is actually triggered.

- Synchronize call to `POST /shutdown` on client side
- Asynchronize explicitly `pulsar().closeAsync()` invocation

(cherry picked from commit 362c4f4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Gracefully shutdown not work with admin cli
9 participants