Skip to content

Commit

Permalink
perf: speed up the first loading of namespace when startup meet 404 (#61
Browse files Browse the repository at this point in the history
)

* perf: speed up then first time loading of namespace when meet 404

* test: fix the number of http requests

* test: fix

* test: use mockserver-netty to refactor test case

* add apache LICENSE-2.0

* feat: add initialize method

* fix

* Update CHANGES.md

* test: use initialize instead of trySync

* fix: change to default empty implementation for compability
  • Loading branch information
Anilople authored May 18, 2024
1 parent bcc4053 commit 3f0979d
Show file tree
Hide file tree
Showing 14 changed files with 353 additions and 212 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Apollo Java 2.3.0
* [add an initialize method to avoid DefaultProviderManager's logic being triggered when using custom ProviderManager.](https://github.com/apolloconfig/apollo-java/pull/50)
* [Implement parsing time based on pattern for @ApolloJsonValue](https://github.com/apolloconfig/apollo-java/pull/53)
* [Enhance to load mocked properties from apollo.cache-dir](https://github.com/apolloconfig/apollo-java/pull/58)
* [perf: speed up the first loading of namespace when startup meet 404](https://github.com/apolloconfig/apollo-java/pull/61)

------------------
All issues and pull requests are [here](https://github.com/apolloconfig/apollo-java/milestone/3?closed=1)
5 changes: 5 additions & 0 deletions apollo-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
<artifactId>log4j-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<scope>test</scope>
</dependency>
<!-- end of test -->
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,9 @@ protected void fireRepositoryChange(String namespace, Properties newProperties)
}
}
}

@Override
public void initialize() {
this.sync();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ public interface ConfigRepository {
* @return the config's source type
*/
ConfigSourceType getSourceType();

/**
* Initialize the repository.
*/
default void initialize() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public DefaultConfig(String namespace, ConfigRepository configRepository) {

private void initialize() {
try {
m_configRepository.initialize();
updateConfig(m_configRepository.getConfig(), m_configRepository.getSourceType());
} catch (Throwable ex) {
Tracer.logError(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ public LocalFileConfigRepository(String namespace, ConfigRepository upstream) {
m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
this.setLocalCacheDir(findLocalCacheDir(), false);
this.setUpstreamRepository(upstream);
this.trySync();
}

void setLocalCacheDir(File baseDir, boolean syncImmediately) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ public RemoteConfigRepository(String namespace) {
m_configNeedForceRefresh = new AtomicBoolean(true);
m_loadConfigFailSchedulePolicy = new ExponentialSchedulePolicy(m_configUtil.getOnErrorRetryInterval(),
m_configUtil.getOnErrorRetryInterval() * 8);
this.trySync();
this.schedulePeriodicRefresh();
this.scheduleLongPollingRefresh();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,19 @@

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.MetaDomainConsts;
import com.ctrip.framework.apollo.core.dto.ApolloConfig;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.junit.After;
import org.junit.Before;

import com.ctrip.framework.apollo.build.MockInjector;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.util.ReflectionTestUtils;
Expand All @@ -67,25 +52,51 @@ public abstract class BaseIntegrationTest {
protected static int refreshInterval;
protected static TimeUnit refreshTimeUnit;
protected static boolean propertiesOrderEnabled;
private Server server;
private MockedConfigService mockedConfigService;
protected Gson gson = new Gson();

@Rule
public TestRule watcher = new TestWatcher() {
protected void starting(Description description) {
logger.info("Starting test: " + description.getMethodName());
}
protected MockedConfigService newMockedConfigService() {
this.mockedConfigService = new MockedConfigService(port);
this.mockedConfigService.init();
this.mockMetaServer();
return this.mockedConfigService;
}

protected void finished(Description description) {
logger.info("Finished test: " + description.getMethodName());
}
};
protected void mockMetaServer() {
mockMetaServer(false);
}

protected void mockMetaServer(boolean failedAtFirstTime) {
final ServiceDTO someServiceDTO = new ServiceDTO();
someServiceDTO.setAppName(someAppName);
someServiceDTO.setInstanceId(someInstanceId);
someServiceDTO.setHomepageUrl(configServiceURL);
this.mockedConfigService.mockMetaServer(failedAtFirstTime, someServiceDTO);
}

public void mockConfigs(
int mockedStatusCode,
ApolloConfig apolloConfig
) {
this.mockConfigs(false, mockedStatusCode, apolloConfig);
}

public void mockConfigs(
boolean failedAtFirstTime,
int mockedStatusCode,
ApolloConfig apolloConfig
) {
this.mockedConfigService.mockConfigs(
failedAtFirstTime, mockedStatusCode, apolloConfig
);
}

@Before
@BeforeEach
public void setUp() throws Exception {
someAppId = "1003171";
someClusterName = "someClusterName";
someDataCenter = "someDC";

refreshInterval = 5;
refreshTimeUnit = TimeUnit.MINUTES;
propertiesOrderEnabled = false;
Expand All @@ -99,71 +110,20 @@ public void setUp() throws Exception {
MockInjector.setInstance(ConfigUtil.class, new MockConfigUtil());
}

@After
@AfterEach
public void tearDown() throws Exception {
//as ConfigService is singleton, so we must manually clear its container
ConfigService.reset();
MockInjector.reset();
System.clearProperty(ConfigConsts.APOLLO_META_KEY);
ReflectionTestUtils.invokeMethod(MetaDomainConsts.class, "reset");

if (server != null && server.isStarted()) {
server.stop();
if (mockedConfigService != null) {
mockedConfigService.close();
mockedConfigService = null;
}
}

/**
* init and start a jetty server, remember to call server.stop when the task is finished
*
* @param handlers
* @throws Exception
*/
protected Server startServerWithHandlers(ContextHandler... handlers) throws Exception {
server = new Server(port);

ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(handlers);
contexts.addHandler(mockMetaServerHandler());

server.setHandler(contexts);
server.start();

return server;
}

protected ContextHandler mockMetaServerHandler() {
return mockMetaServerHandler(false);
}

protected ContextHandler mockMetaServerHandler(final boolean failedAtFirstTime) {
final ServiceDTO someServiceDTO = new ServiceDTO();
someServiceDTO.setAppName(someAppName);
someServiceDTO.setInstanceId(someInstanceId);
someServiceDTO.setHomepageUrl(configServiceURL);
final AtomicInteger counter = new AtomicInteger(0);

ContextHandler context = new ContextHandler("/services/config");
context.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
if (failedAtFirstTime && counter.incrementAndGet() == 1) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
baseRequest.setHandled(true);
return;
}
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_OK);

response.getWriter().println(gson.toJson(Lists.newArrayList(someServiceDTO)));

baseRequest.setHandled(true);
}
});

return context;
}

protected void setRefreshInterval(int refreshInterval) {
BaseIntegrationTest.refreshInterval = refreshInterval;
}
Expand Down
Loading

0 comments on commit 3f0979d

Please sign in to comment.