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

perf: speed up the first loading of namespace when startup meet 404 #61

Merged
merged 10 commits into from
May 18, 2024

Conversation

Anilople
Copy link
Contributor

@Anilople Anilople commented May 7, 2024

What's the purpose of this PR

Speed up the user's startup time,

by decrease the number of http requests.

Which issue(s) this PR fixes:

Fixes #60

Brief changelog

before change, it use 11494 ms to load 10 namespace when meet 404,
before-change.log

after delete 2 http requests when context init, it use 1490 ms.
after-change.log

i.e from 11494 ms to 1490 ms.

the code in


will ensure pull at least one time from remote when startup.

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Read the Contributing Guide before making this pull request.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit tests to verify the code.
  • Run mvn clean test to make sure this pull request doesn't break anything.
  • Update the CHANGES log.

Summary by CodeRabbit

  • New Features

    • Introduced a new initialization process in the configuration repository, enhancing the setup mechanism.
  • Bug Fixes

    • Adjusted initialization calls to ensure proper configuration setup without redundant sync calls.
  • Tests

    • Added assertions in tests to verify the source type before and after initialization, improving test coverage and reliability.

@Anilople Anilople added the enhancement New feature or request label May 7, 2024
Copy link
Contributor

coderabbitai bot commented May 7, 2024

Walkthrough

The recent changes in the apollo-client module primarily focus on improving the initialization process to speed up the user's startup time. The changes include adding an initialize() method to various classes and interfaces, modifying constructors to avoid initial synchronization calls, and updating tests to reflect these changes.

Changes

File Path Change Summary
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java Added initialize() method to call sync().
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java Added default initialize() method to the interface.
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java Added call to m_configRepository.initialize() in initialize() method.
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java Commented out trySync() call in the constructor.
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java Commented out trySync() call in the constructor.
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java Added assertion to check source type before and after initialization in testOnRepositoryChange.

Assessment against linked issues

Objective (Issue #60) Addressed Explanation
Speed up user's startup time by reducing IO calls
Fast fail when encountering errors

In the land of code where rabbits play,
Initialization now speeds the way.
Sync calls deferred, constructors light,
Users' startup times take flight.
With tests to check, and code so bright,
Apollo's changes feel just right. 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@Anilople Anilople changed the title perf: speed up then first time loading of namespace when meet 404 by decrease the number of http requests perf: speed up the first time loading of namespace when meet 404 by decrease the number of http requests May 7, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between bcc4053 and 4a35cca.
Files selected for processing (2)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java (1 hunks)
Files skipped from review due to trivial changes (2)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 4a35cca and bd66c13.
Files selected for processing (1)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java (1 hunks)
Additional comments not posted (4)
apollo-client/src/test/java/com/ctrip/framework/apollo/internals/RemoteConfigRepositoryTest.java (4)

Line range hint 58-104: Setup method is correctly implemented and provides a controlled environment for the tests.


Line range hint 106-109: Teardown method correctly cleans up after tests to prevent side effects.


Line range hint 273-323: The testLongPollingRefresh method effectively tests the long polling refresh functionality and correctly verifies that change listeners are notified.


Line range hint 325-354: The testAssembleQueryConfigUrl method correctly tests the URL assembly logic, ensuring that all parameters are included and properly encoded.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between bd66c13 and 8e3fd24.
Files selected for processing (1)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java (1 hunks)

Comment on lines 189 to 190
assertEquals(ConfigSourceType.LOCAL, localFileConfigRepository.getSourceType());
localFileConfigRepository.trySync();
Copy link
Contributor

Choose a reason for hiding this comment

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

The call to trySync() in the test might not reflect the actual behavior anymore.

Given the changes in the main class where trySync() calls are commented out, this test might fail or not behave as expected because it assumes trySync() is operational. Consider adjusting the test to reflect the new logic, or if trySync() is conditionally called, ensure this condition is replicated in the test setup.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Out of diff range and nitpick comments (1)
apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java (1)

Line range hint 220-220: Use encrypted sockets to enhance security.

- ServerSocket socket = new ServerSocket(0);
+ SSLServerSocket socket = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(0);
Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 8e3fd24 and 060fd4d.
Files selected for processing (6)
  • apollo-client/pom.xml (1 hunks)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/BaseIntegrationTest.java (3 hunks)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/MockedConfigService.java (1 hunks)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java (23 hunks)
  • apollo-client/src/test/resources/log4j2.xml (1 hunks)
  • pom.xml (1 hunks)
Files skipped from review due to trivial changes (2)
  • apollo-client/pom.xml
  • pom.xml
Additional comments not posted (2)
apollo-client/src/test/resources/log4j2.xml (1)

32-32: Set logging level for "org.mockserver.log" to WARN to reduce verbosity in test logs.

apollo-client/src/test/java/com/ctrip/framework/apollo/integration/ConfigIntegrationTest.java (1)

Line range hint 19-486: The integration tests in ConfigIntegrationTest are comprehensive and effectively use mocks to isolate test scenarios.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 060fd4d and 2b27120.
Files selected for processing (1)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/MockedConfigService.java (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/MockedConfigService.java

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 2b27120 and 366766f.
Files selected for processing (5)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepository.java
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/RemoteConfigRepository.java
Additional comments not posted (3)
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java (1)

57-60: Addition of initialize() method in the interface standardizes initialization across different repository types.

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java (1)

77-80: Implementation of initialize() method correctly invokes sync() to ensure repository synchronization during initialization.

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java (1)

74-74: Modification to call m_configRepository.initialize() aligns with the new initialization protocol and ensures robust error handling.

@Anilople Anilople changed the title perf: speed up the first time loading of namespace when meet 404 by decrease the number of http requests perf: speed up the first time loading of namespace when meet 404 May 10, 2024
@Anilople Anilople changed the title perf: speed up the first time loading of namespace when meet 404 perf: speed up the first loading of namespace when meet 404 May 10, 2024
@Anilople Anilople changed the title perf: speed up the first loading of namespace when meet 404 perf: speed up the first loading of namespace when startup meet 404 May 10, 2024
@Anilople Anilople requested a review from a team May 10, 2024 13:41

@Override
public void initialize() {
this.sync();
Copy link
Member

Choose a reason for hiding this comment

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

Is it better to call trySync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change to trySync here will slower startup. Let me try to illustrate it.


1. everything from the rate limiter in RemoteConfigRepository

If we do not wait for 2 consecutive calls to method sync, the rateLimter in RemoteConfigRepository will block current thread 500ms on the second call because code m_loadConfigRateLimiter.tryAcquire(5, TimeUnit.SECONDS), that is why so slower when startup.

if (!m_loadConfigRateLimiter.tryAcquire(5, TimeUnit.SECONDS)) {
//wait at most 5 seconds
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
}

sequenceDiagram
RemoteConfigRepository ->> RemoteConfigRepository: sync
RemoteConfigRepository ->> RemoteConfigRepository: loadApolloConfig
RemoteConfigRepository ->> m_loadConfigRateLimiter: tryAcquire(5, TimeUnit.SECONDS)
alt if Acquire success
	m_loadConfigRateLimiter -->> RemoteConfigRepository: return immediately
else Acquire fail
	m_loadConfigRateLimiter -->> RemoteConfigRepository: block current thread 500ms
end
Loading

2. how to solve it?

There are 2 solution to speed up.

solution 1: forbid 2 consecutive calls to method sync,

solution 2: use another method on m_loadConfigRateLimiter let it won't block current thread 500ms .


3. Back to talk about method initialize in DefaultConfig.

According to the code

private void initialize() {
try {
updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType());
} catch (Throwable ex) {
Tracer.logError(ex);
logger.warn("Init Apollo Local Config failed - namespace: {}, reason: {}.",
m_namespace, ExceptionUtil.getDetailMessage(ex));

m_configRepository.getConfig() will invoke method sync.

When we change to code

  private void initialize() {
    try {
      m_configRepository.initialize();
      updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType());
    } catch (Throwable ex) {
      Tracer.logError(ex);
      logger.warn("Init Apollo Local Config failed - namespace: {}, reason: {}.",
          m_namespace, ExceptionUtil.getDetailMessage(ex));
    } finally {

m_configRepository.initialize(); and m_configRepository.getConfig() alway invoke method sync,
i.e 2 consecutive calls to method sync, that will let startup slower.

But the different in m_configRepository.initialize();, if we use sync instead of trySync,
the exception will throw quickly, so updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType()); won't execute,

i.e choose solution 1: forbid 2 consecutive calls to method sync to speed up.

That's why use sync instead of trySync here.

Maybe there is better solution here?

Copy link
Member

Choose a reason for hiding this comment

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

I agree with you. Let's keep it as it is.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Out of diff range and nitpick comments (3)
CHANGES.md (3)

Line range hint 1-1: Ensure headings are surrounded by blank lines for proper markdown formatting.


8-8: Lists should be surrounded by blank lines to adhere to markdown best practices.


14-14: Ensure the file ends with a single newline character.

Review Details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits Files that changed from the base of the PR and between 366766f and 406042e.
Files selected for processing (3)
  • CHANGES.md (1 hunks)
  • apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java (1 hunks)
  • apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java (1 hunks)
Additional comments not posted (2)
apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigRepository.java (1)

56-60: The addition of a default initialize() method is a good practice. It ensures backward compatibility with existing implementations of this interface.

apollo-client/src/test/java/com/ctrip/framework/apollo/internals/LocalFileConfigRepositoryTest.java (1)

189-190: The new assertions in testOnRepositoryChange correctly verify the source type before and after initialization, ensuring the initialize() method functions as expected.

Copy link
Member

@nobodyiam nobodyiam left a comment

Choose a reason for hiding this comment

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

LGTM

@nobodyiam nobodyiam merged commit 3f0979d into apolloconfig:main May 18, 2024
7 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators May 18, 2024
@nobodyiam nobodyiam added this to the 2.3.0 milestone Aug 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feature request: speed up user's startup time as fast as possible
2 participants