Adds a new completion state to the deployer (#13340)

* Adjust the order of events in Deployer

* Format code

* Add completion state

* Format code

* Format code

* Format code

* Marking completion as final state

* Add some comments

* Add some comments

* Fix application state calculate

* Compatible with started state

* Fix tests
This commit is contained in:
TomlongTK 2023-11-29 20:58:43 +08:00 committed by GitHub
parent 7e0954b8cf
commit 3f48269562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 218 additions and 102 deletions

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_MONITOR_EXCEPTION;
import static org.apache.dubbo.common.deploy.DeployState.COMPLETION;
import static org.apache.dubbo.common.deploy.DeployState.FAILED;
import static org.apache.dubbo.common.deploy.DeployState.PENDING;
import static org.apache.dubbo.common.deploy.DeployState.STARTED;
@ -56,12 +57,17 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
@Override
public boolean isRunning() {
return state == STARTING || state == STARTED;
return state == STARTING || state == STARTED || state == COMPLETION;
}
@Override
public boolean isStarted() {
return state == STARTED;
return state == STARTED || state == COMPLETION;
}
@Override
public boolean isCompletion() {
return state == COMPLETION;
}
@Override
@ -135,6 +141,22 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
}
protected void setCompletion() {
this.state = COMPLETION;
for (DeployListener<E> listener : listeners) {
try {
listener.onCompletion(scopeModel);
} catch (Throwable e) {
logger.error(
COMMON_MONITOR_EXCEPTION,
"",
"",
getIdentifier() + " an exception occurred when handle completion event",
e);
}
}
}
protected void setStopping() {
this.state = STOPPING;
for (DeployListener<E> listener : listeners) {

View File

@ -24,13 +24,35 @@ public interface DeployListener<E extends ScopeModel> {
*/
void onInitialize(E scopeModel);
/**
* Triggered before starting module.
*/
void onStarting(E scopeModel);
/**
* Triggered before registering and exposing the service.
*/
void onStarted(E scopeModel);
/**
* Triggered after deployer startup is complete.
*/
default void onCompletion(E scopeModel) {}
/**
* Triggered before the app is destroyed,
* can do some customized things before offline the service and destroy reference.
*/
void onStopping(E scopeModel);
/**
* Triggered after the application is destroyed,
* can do some customized things after the service is offline and the reference is destroyed.
*/
void onStopped(E scopeModel);
/**
* Useful to do something when deployer was failed.
*/
void onFailure(E scopeModel, Throwable cause);
}

View File

@ -28,6 +28,9 @@ public class DeployListenerAdapter<E extends ScopeModel> implements DeployListen
@Override
public void onStarted(E scopeModel) {}
@Override
public void onCompletion(E scopeModel) {}
@Override
public void onStopping(E scopeModel) {}

View File

@ -40,6 +40,11 @@ public enum DeployState {
*/
STARTED,
/**
* Completion
*/
COMPLETION,
/**
* Stopping
*/

View File

@ -55,6 +55,8 @@ public interface Deployer<E extends ScopeModel> {
*/
boolean isStarted();
boolean isCompletion();
/**
* @return true if the component is starting.
* @see #isStarted()

View File

@ -294,6 +294,10 @@ public final class DubboBootstrap {
return applicationDeployer.isStarted();
}
public boolean isCompletion() {
return applicationDeployer.isCompletion();
}
/**
* @return true if the dubbo application is stopping.
* @see #isStopped()
@ -524,8 +528,7 @@ public final class DubboBootstrap {
private <S> ServiceConfig createServiceConfig(String id, Consumer<ServiceBuilder<S>> consumerBuilder) {
ServiceBuilder builder = createServiceBuilder(id);
consumerBuilder.accept(builder);
ServiceConfig serviceConfig = builder.build();
return serviceConfig;
return builder.build();
}
public DubboBootstrap services(List<ServiceConfig> serviceConfigs) {
@ -561,8 +564,7 @@ public final class DubboBootstrap {
private <S> ReferenceConfig createReferenceConfig(String id, Consumer<ReferenceBuilder<S>> consumerBuilder) {
ReferenceBuilder builder = createReferenceBuilder(id);
consumerBuilder.accept(builder);
ReferenceConfig referenceConfig = builder.build();
return referenceConfig;
return builder.build();
}
public DubboBootstrap references(List<ReferenceConfig> referenceConfigs) {
@ -599,8 +601,7 @@ public final class DubboBootstrap {
private ProviderConfig createProviderConfig(String id, Consumer<ProviderBuilder> builderConsumer) {
ProviderBuilder builder = createProviderBuilder(id);
builderConsumer.accept(builder);
ProviderConfig providerConfig = builder.build();
return providerConfig;
return builder.build();
}
public DubboBootstrap provider(ProviderConfig providerConfig) {
@ -632,8 +633,7 @@ public final class DubboBootstrap {
private ConsumerConfig createConsumerConfig(String id, Consumer<ConsumerBuilder> builderConsumer) {
ConsumerBuilder builder = createConsumerBuilder(id);
builderConsumer.accept(builder);
ConsumerConfig consumerConfig = builder.build();
return consumerConfig;
return builder.build();
}
public DubboBootstrap consumer(ConsumerConfig consumerConfig) {

View File

@ -361,7 +361,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
configManager.loadConfigsOfTypeFromProps(RegistryConfig.class);
List<RegistryConfig> defaultRegistries = configManager.getDefaultRegistries();
if (defaultRegistries.size() > 0) {
if (!defaultRegistries.isEmpty()) {
defaultRegistries.stream()
.filter(this::isUsedRegistryAsConfigCenter)
.map(this::registryAsConfigCenter)
@ -511,9 +511,8 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
defaultRegistries.stream()
.filter(this::isUsedRegistryAsMetadataCenter)
.map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride))
.forEach(metadataReportConfig -> {
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig);
});
.forEach(metadataReportConfig ->
overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig));
}
}
@ -693,7 +692,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
// if is started and no new module, just return
if (isStarted() && !hasPendingModule) {
if ((isStarted() || isCompletion()) && !hasPendingModule) {
return CompletableFuture.completedFuture(false);
}
@ -812,7 +811,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// start internal module
ModuleDeployer internalModuleDeployer =
applicationModel.getInternalModule().getDeployer();
if (!internalModuleDeployer.isStarted()) {
if (!internalModuleDeployer.isCompletion()) {
Future future = internalModuleDeployer.start();
// wait for internal module startup
try {
@ -1015,7 +1014,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// refresh for 30 times (default for 30s) when deployer is not started, prevent submit
// too many revision
if (instanceRefreshScheduleTimes.incrementAndGet() % 30 != 0 && !isStarted()) {
if (instanceRefreshScheduleTimes.incrementAndGet() % 30 != 0 && !isCompletion()) {
return;
}
@ -1190,6 +1189,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
case STARTED:
onStarted();
break;
case COMPLETION:
onCompletion();
break;
case STARTING:
onStarting();
break;
@ -1221,8 +1223,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
private DeployState calculateState() {
DeployState newState = DeployState.UNKNOWN;
int pending = 0, starting = 0, started = 0, stopping = 0, stopped = 0, failed = 0;
int total = 0, pending = 0, starting = 0, started = 0, completion = 0, stopping = 0, stopped = 0, failed = 0;
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
ModuleDeployer deployer = moduleModel.getDeployer();
if (deployer == null) {
@ -1231,6 +1232,8 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
pending++;
} else if (deployer.isStarting()) {
starting++;
} else if (deployer.isCompletion()) {
completion++;
} else if (deployer.isStarted()) {
started++;
} else if (deployer.isStopping()) {
@ -1240,39 +1243,37 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
} else if (deployer.isFailed()) {
failed++;
}
total++;
}
// any module is failed
if (failed > 0) {
newState = DeployState.FAILED;
} else if (started > 0) {
if (pending + starting + stopping + stopped == 0) {
// all modules have been started
newState = DeployState.STARTED;
} else if (pending + starting > 0) {
// some module is pending and some is started
newState = DeployState.STARTING;
} else if (stopping + stopped > 0) {
newState = DeployState.STOPPING;
}
} else if (starting > 0) {
// any module is starting
newState = DeployState.STARTING;
} else if (pending > 0) {
if (starting + starting + stopping + stopped == 0) {
// all modules have not starting or started
newState = DeployState.PENDING;
} else if (stopping + stopped > 0) {
// some is pending and some is stopping or stopped
newState = DeployState.STOPPING;
}
} else if (stopping > 0) {
// some is stopping and some stopped
newState = DeployState.STOPPING;
} else if (stopped > 0) {
// all modules are stopped
newState = DeployState.STOPPED;
return DeployState.FAILED;
}
return newState;
// all modules have not starting or started
if (pending == total) {
return DeployState.PENDING;
}
// all modules have completed
if (completion == total) {
return DeployState.COMPLETION;
}
// all modules are stopped
if (stopped == total) {
return DeployState.STOPPED;
}
// some module is starting or pending, it's in starting state
if (starting > 0 || pending > 0) {
return DeployState.STARTING;
}
// some module is stopping or stopped, it's in stopping state
if (stopping > 0 || stopped > 0) {
return DeployState.STOPPING;
}
// all modules have been started
if (started > 0) {
return DeployState.STARTED;
}
return DeployState.UNKNOWN;
}
private void onInitialize() {
@ -1291,7 +1292,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
private void doExportMetadataService() {
if (!isStarting() && !isStarted()) {
if (!isStarting() && !isStarted() && !isCompletion()) {
return;
}
for (DeployListener<ApplicationModel> listener : listeners) {
@ -1313,7 +1314,8 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private void onStarting() {
// pending -> starting
// started -> starting
if (!(isPending() || isStarted())) {
// completion -> starting
if (!(isPending() || isStarted() || isCompletion())) {
return;
}
setStarting();
@ -1324,23 +1326,34 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
private void onStarted() {
// starting -> started
if (!isStarting()) {
return;
}
setStarted();
startMetricsCollector();
if (logger.isInfoEnabled()) {
logger.info(getIdentifier() + " is ready.");
}
// refresh metadata
try {
// starting -> started
if (!isStarting()) {
if (registered) {
ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
}
} catch (Exception e) {
logger.error(CONFIG_REFRESH_INSTANCE_ERROR, "", "", "Refresh instance and metadata error.", e);
}
}
private void onCompletion() {
try {
// started -> completion
if (!isStarted()) {
return;
}
setStarted();
startMetricsCollector();
setCompletion();
if (logger.isInfoEnabled()) {
logger.info(getIdentifier() + " is ready.");
}
// refresh metadata
try {
if (registered) {
ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
}
} catch (Exception e) {
logger.error(CONFIG_REFRESH_INSTANCE_ERROR, "", "", "Refresh instance and metadata error.", e);
logger.info(getIdentifier() + " has completed.");
}
} finally {
// complete future

View File

@ -165,7 +165,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
}
try {
if (isStarting() || isStarted()) {
if (isStarting() || isStarted() || isCompletion()) {
return startFuture;
}
@ -196,6 +196,9 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
// check reference config
checkReferences();
// publish module completion event
onModuleCompletion();
// complete module start future after application state changed
completeStartFuture(true);
} else {
@ -203,6 +206,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
try {
// wait for export finish
waitExportFinish();
// wait for refer finish
waitReferFinish();
@ -214,6 +218,9 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
// check reference config
checkReferences();
// publish module completion event
onModuleCompletion();
} catch (Throwable e) {
logger.warn(
CONFIG_FAILED_WAIT_EXPORT_REFER,
@ -243,7 +250,7 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
}
private boolean hasExportedServices() {
return configManager.getServices().size() > 0;
return !configManager.getServices().isEmpty();
}
@Override
@ -367,6 +374,14 @@ public class DefaultModuleDeployer extends AbstractDeployer<ModuleModel> impleme
}
}
private void onModuleCompletion() {
if (isStarted()) {
setCompletion();
logger.info(getIdentifier() + " has completed.");
applicationDeployer.notifyModuleChanged(moduleModel, DeployState.COMPLETION);
}
}
private void onModuleFailed(String msg, Throwable ex) {
try {
try {

View File

@ -39,6 +39,9 @@ public class ExporterDeployListener implements ApplicationDeployListener, Priori
@Override
public synchronized void onStarted(ApplicationModel applicationModel) {}
@Override
public void onCompletion(ApplicationModel scopeModel) {}
@Override
public synchronized void onStopping(ApplicationModel scopeModel) {}

View File

@ -264,7 +264,7 @@ class DubboBootstrapTest {
.start();
Assertions.assertTrue(bootstrap.isInitialized());
Assertions.assertTrue(bootstrap.isStarted());
Assertions.assertTrue(bootstrap.isCompletion());
Assertions.assertFalse(bootstrap.isStopped());
ApplicationModel applicationModel = bootstrap.getApplicationModel();

View File

@ -25,6 +25,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConfigKeys;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
@ -32,6 +33,7 @@ import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.SysProps;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.api.Greeting;
import org.apache.dubbo.config.context.ConfigMode;
import org.apache.dubbo.config.mock.GreetingLocal2;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.registry.client.migration.MigrationInvoker;
@ -475,10 +477,10 @@ class MultiInstanceTest {
ModuleDeployer moduleDeployer1 = serviceConfig1.getScopeModel().getDeployer();
moduleDeployer1.start().get();
Assertions.assertTrue(moduleDeployer1.isStarted());
Assertions.assertTrue(moduleDeployer1.isCompletion());
ModuleDeployer internalModuleDeployer =
applicationModel.getInternalModule().getDeployer();
Assertions.assertTrue(internalModuleDeployer.isStarted());
Assertions.assertTrue(internalModuleDeployer.isCompletion());
FrameworkServiceRepository frameworkServiceRepository =
applicationModel.getFrameworkModel().getServiceRepository();
@ -606,7 +608,7 @@ class MultiInstanceTest {
// 1. start module1 and wait
ModuleDeployer moduleDeployer1 = serviceConfig1.getScopeModel().getDeployer();
moduleDeployer1.start().get();
Assertions.assertEquals(DeployState.STARTED, moduleDeployer1.getState());
Assertions.assertEquals(DeployState.COMPLETION, moduleDeployer1.getState());
ApplicationModel applicationModel = providerBootstrap.getApplicationModel();
ApplicationDeployer applicationDeployer = applicationModel.getDeployer();
@ -617,9 +619,9 @@ class MultiInstanceTest {
// 2. start application after module1 is started
providerBootstrap.start();
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertEquals(
DeployState.STARTED, defaultModule.getDeployer().getState());
DeployState.COMPLETION, defaultModule.getDeployer().getState());
// 3. add module2 and re-start application
ServiceConfig serviceConfig2 = new ServiceConfig();
@ -629,9 +631,9 @@ class MultiInstanceTest {
ModuleModel moduleModel2 =
providerBootstrap.newModule().service(serviceConfig2).getModuleModel();
providerBootstrap.start();
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertEquals(
DeployState.STARTED, moduleModel2.getDeployer().getState());
DeployState.COMPLETION, moduleModel2.getDeployer().getState());
// 4. add module3 and start module3
ServiceConfig serviceConfig3 = new ServiceConfig();
@ -641,9 +643,9 @@ class MultiInstanceTest {
ModuleModel moduleModel3 =
providerBootstrap.newModule().service(serviceConfig3).getModuleModel();
moduleModel3.getDeployer().start().get();
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertEquals(
DeployState.STARTED, moduleModel3.getDeployer().getState());
DeployState.COMPLETION, moduleModel3.getDeployer().getState());
} finally {
if (providerBootstrap != null) {
@ -697,10 +699,10 @@ class MultiInstanceTest {
// 2. start application after module1 is starting
providerBootstrap.start();
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(DeployState.STARTED, moduleDeployer1.getState());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertEquals(DeployState.COMPLETION, moduleDeployer1.getState());
Assertions.assertEquals(
DeployState.STARTED, defaultModule.getDeployer().getState());
DeployState.COMPLETION, defaultModule.getDeployer().getState());
} finally {
if (providerBootstrap != null) {
@ -713,6 +715,7 @@ class MultiInstanceTest {
void testOldApiDeploy() throws Exception {
try {
SysProps.setProperty(ConfigKeys.DUBBO_CONFIG_MODE, ConfigMode.OVERRIDE.name());
// provider app
ApplicationModel providerApplicationModel = ApplicationModel.defaultModel();
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
@ -731,17 +734,19 @@ class MultiInstanceTest {
Map<DeployState, Long> serviceDeployEventMap = serviceDeployEventHandler.deployEventMap;
Assertions.assertFalse(serviceDeployEventMap.containsKey(DeployState.STARTING));
Assertions.assertFalse(serviceDeployEventMap.containsKey(DeployState.STARTED));
Assertions.assertFalse(serviceDeployEventMap.containsKey(DeployState.COMPLETION));
// export service and start module
serviceConfig.export();
// expect internal module is started
Assertions.assertTrue(
providerApplicationModel.getInternalModule().getDeployer().isStarted());
providerApplicationModel.getInternalModule().getDeployer().isCompletion());
// expect service module is starting
Assertions.assertTrue(serviceDeployEventMap.containsKey(DeployState.STARTING));
// wait for service module started
serviceConfig.getScopeModel().getDeployer().getStartFuture().get();
Assertions.assertTrue(serviceDeployEventMap.containsKey(DeployState.STARTED));
Assertions.assertTrue(serviceDeployEventMap.containsKey(DeployState.COMPLETION));
// consumer app
ApplicationModel consumerApplicationModel = ApplicationModel.defaultModel();
@ -760,16 +765,18 @@ class MultiInstanceTest {
Map<DeployState, Long> deployEventMap = referDeployEventHandler.deployEventMap;
Assertions.assertFalse(deployEventMap.containsKey(DeployState.STARTING));
Assertions.assertFalse(deployEventMap.containsKey(DeployState.STARTED));
Assertions.assertFalse(deployEventMap.containsKey(DeployState.COMPLETION));
// get ref proxy and start module
DemoService demoService = referenceConfig.get();
// expect internal module is started
Assertions.assertTrue(
consumerApplicationModel.getInternalModule().getDeployer().isStarted());
consumerApplicationModel.getInternalModule().getDeployer().isCompletion());
Assertions.assertTrue(deployEventMap.containsKey(DeployState.STARTING));
// wait for reference module started
referenceConfig.getScopeModel().getDeployer().getStartFuture().get();
Assertions.assertTrue(deployEventMap.containsKey(DeployState.STARTED));
Assertions.assertTrue(deployEventMap.containsKey(DeployState.COMPLETION));
// stop consumer app
consumerApplicationModel.destroy();
@ -919,6 +926,12 @@ class MultiInstanceTest {
deployEventMap.put(DeployState.STARTED, System.currentTimeMillis());
}
@Override
public void onCompletion(ModuleModel scopeModel) {
Assertions.assertEquals(moduleModel, scopeModel);
deployEventMap.put(DeployState.COMPLETION, System.currentTimeMillis());
}
@Override
public void onStopping(ModuleModel scopeModel) {
Assertions.assertEquals(moduleModel, scopeModel);

View File

@ -151,7 +151,7 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
// ServiceConfig is exported or not
Assertions.assertFalse(serviceConfig.isExported());
// ServiceConfig's exportedUrl has values or not
Assertions.assertEquals(serviceConfig.getExportedUrls().size(), 0);
Assertions.assertEquals(0, serviceConfig.getExportedUrls().size());
// DubboBootstrap is pending or not
Assertions.assertTrue(DubboBootstrap.getInstance().isPending());
// DubboBootstrap is initialized or not
@ -195,13 +195,15 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
// DubboBootstrap is pending or not
Assertions.assertFalse(DubboBootstrap.getInstance().isPending());
// DubboBootstrap is started or not
Assertions.assertTrue(DubboBootstrap.getInstance().isStarted());
Assertions.assertTrue(DubboBootstrap.getInstance().isCompletion());
// DubboBootstrap is running
Assertions.assertTrue(DubboBootstrap.getInstance().isRunning());
// DubboBootstrap is shutdown or not
Assertions.assertFalse(DubboBootstrap.getInstance().isStopped());
// Service has been exported or not
Assertions.assertTrue(this.serviceConfig.isExported());
// There is exported urls or not
Assertions.assertEquals(this.serviceConfig.getExportedUrls().size(), 1);
Assertions.assertEquals(1, this.serviceConfig.getExportedUrls().size());
URL exportedUrl = this.serviceConfig.getExportedUrls().get(0);
// Protocol name is right or not
Assertions.assertEquals(exportedUrl.getProtocol(), PROTOCOL_NAME);
@ -231,7 +233,7 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
serviceConfig.getScopeModel().getBeanFactory().getBean(MetadataService.class);
// Exported url is right or not in InMemoryWritableMetadataService
Assertions.assertEquals(
inMemoryWritableMetadataService.getExportedURLs().size(), 1);
1, inMemoryWritableMetadataService.getExportedURLs().size());
// MetadataInfo exists or not in InMemoryWritableMetadataService
Assertions.assertFalse(
inMemoryWritableMetadataService.getMetadataInfos().isEmpty());
@ -243,12 +245,12 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
.isEmpty());
// MetadataInfo has reported or not has service or not
Assertions.assertEquals(
1,
inMemoryWritableMetadataService
.getMetadataInfos()
.get(0)
.getServices()
.size(),
1);
.size());
// obtain the service's key
String key = SingleRegistryCenterIntegrationService.class.getName() + ":" + PROTOCOL_NAME;
MetadataInfo.ServiceInfo serviceInfo = inMemoryWritableMetadataService
@ -278,10 +280,10 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
ExtensionLoader.getExtensionLoader(ServiceListener.class).getExtension("exported");
Assertions.assertNotNull(singleRegistryCenterExportedServiceListener);
Assertions.assertEquals(
1,
singleRegistryCenterExportedServiceListener
.getExportedServices()
.size(),
1);
.size());
Assertions.assertEquals(
SingleRegistryCenterIntegrationService.class,
singleRegistryCenterExportedServiceListener
@ -382,12 +384,13 @@ class SingleRegistryCenterDubboProtocolIntegrationTest implements IntegrationTes
Assertions.assertTrue(serviceDiscoveryRegistryDirectory.isShouldRegister());
// ServiceDiscoveryRegistryDirectory's registered consumer url is right or not
Assertions.assertEquals(
serviceDiscoveryRegistryDirectory.getRegisteredConsumerUrl().getCategory(), CONSUMERS_CATEGORY);
CONSUMERS_CATEGORY,
serviceDiscoveryRegistryDirectory.getRegisteredConsumerUrl().getCategory());
// ServiceDiscoveryRegistryDirectory's registry is right or not
Assertions.assertTrue(serviceDiscoveryRegistryDirectory.getRegistry() instanceof ListenerRegistryWrapper);
// Directory's invokers are right or not
Assertions.assertEquals(
serviceDiscoveryRegistryDirectory.getAllInvokers().size(), 1);
1, serviceDiscoveryRegistryDirectory.getAllInvokers().size());
Assertions.assertEquals(
serviceDiscoveryRegistryDirectory.getInvokers(), serviceDiscoveryRegistryDirectory.getAllInvokers());
}

View File

@ -77,6 +77,11 @@ public class DubboDeployApplicationListener
publishApplicationEvent(DeployState.STARTED);
}
@Override
public void onCompletion(ApplicationModel scopeModel) {
publishApplicationEvent(DeployState.COMPLETION);
}
@Override
public void onStopping(ApplicationModel scopeModel) {
publishApplicationEvent(DeployState.STOPPING);
@ -103,6 +108,11 @@ public class DubboDeployApplicationListener
publishModuleEvent(DeployState.STARTED);
}
@Override
public void onCompletion(ModuleModel scopeModel) {
publishModuleEvent(DeployState.COMPLETION);
}
@Override
public void onStopping(ModuleModel scopeModel) {
publishModuleEvent(DeployState.STOPPING);

View File

@ -49,17 +49,18 @@ class KeepRunningOnSpringClosedTest {
// No need check and wait
DubboStateListener dubboStateListener = providerContext.getBean(DubboStateListener.class);
Assertions.assertEquals(DeployState.STARTED, dubboStateListener.getState());
Assertions.assertEquals(DeployState.COMPLETION, dubboStateListener.getState());
ModuleModel moduleModel = providerContext.getBean(ModuleModel.class);
ModuleDeployer moduleDeployer = moduleModel.getDeployer();
Assertions.assertTrue(moduleDeployer.isStarted());
Assertions.assertTrue(moduleDeployer.isCompletion());
ApplicationDeployer applicationDeployer =
moduleModel.getApplicationModel().getDeployer();
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(true, applicationDeployer.isStarted());
Assertions.assertEquals(false, applicationDeployer.isStopped());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertTrue(applicationDeployer.isCompletion());
Assertions.assertTrue(applicationDeployer.isStarted());
Assertions.assertFalse(applicationDeployer.isStopped());
Assertions.assertNotNull(DubboSpringInitializer.findBySpringContext(providerContext));
// close spring context
@ -67,9 +68,10 @@ class KeepRunningOnSpringClosedTest {
// Expect 2: dubbo application will not be destroyed after closing spring context cause
// setKeepRunningOnSpringClosed(true)
Assertions.assertEquals(DeployState.STARTED, applicationDeployer.getState());
Assertions.assertEquals(true, applicationDeployer.isStarted());
Assertions.assertEquals(false, applicationDeployer.isStopped());
Assertions.assertEquals(DeployState.COMPLETION, applicationDeployer.getState());
Assertions.assertTrue(applicationDeployer.isCompletion());
Assertions.assertTrue(applicationDeployer.isStarted());
Assertions.assertFalse(applicationDeployer.isStopped());
Assertions.assertNull(DubboSpringInitializer.findBySpringContext(providerContext));
} finally {
DubboBootstrap.getInstance().stop();

View File

@ -40,7 +40,7 @@ public class DeployerReadinessProbe implements ReadinessProbe {
List<ApplicationModel> applicationModels = frameworkModel.getApplicationModels();
for (ApplicationModel applicationModel : applicationModels) {
for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
if (!moduleModel.getDeployer().isStarted()) {
if (!moduleModel.getDeployer().isCompletion()) {
return false;
}
}

View File

@ -63,7 +63,7 @@ class ReadyTest {
Mockito.when(applicationModel.getModuleModels()).thenReturn(Arrays.asList(moduleModel));
Mockito.when(applicationModel.getApplicationConfigManager()).thenReturn(manager);
Mockito.when(moduleModel.getDeployer()).thenReturn(moduleDeployer);
Mockito.when(moduleDeployer.isStarted()).thenReturn(true);
Mockito.when(moduleDeployer.isCompletion()).thenReturn(true);
ExtensionLoader loader = Mockito.mock(ExtensionLoader.class);
Mockito.when(frameworkModel.getExtensionLoader(ReadinessProbe.class)).thenReturn(loader);
@ -83,7 +83,7 @@ class ReadyTest {
Assertions.assertEquals("true", result);
Assertions.assertEquals(commandContext.getHttpCode(), 200);
Mockito.when(moduleDeployer.isStarted()).thenReturn(false);
Mockito.when(moduleDeployer.isCompletion()).thenReturn(false);
result = ready.execute(commandContext, new String[0]);
Assertions.assertEquals("false", result);
Assertions.assertEquals(commandContext.getHttpCode(), 503);

View File

@ -49,6 +49,9 @@ public class CertDeployerListener implements ApplicationDeployListener {
@Override
public void onStarted(ApplicationModel scopeModel) {}
@Override
public void onCompletion(ApplicationModel scopeModel) {}
@Override
public void onStopping(ApplicationModel scopeModel) {
if (dubboCertManager != null) {