Skip to content

Commit

Permalink
[3.0] Refactor application/module deploy processing and events (#8824)
Browse files Browse the repository at this point in the history
* Init SpringExtensionInjector in DubboInfraBeanRegisterPostProcessor

* Refactor application/module deployer start and listener

* Refactor Dubbo spring initialization and events

* Adjust shutdown hook callback call chain

* Fix license

* Add spring context module reload test

* Fix deadlock of ApplicationModel module while destroy

* Catch error while add/remove java shutdown hook

* Waiting for dubbo start in spring application

* polish deploy log

* Rename DubboSpringInitializaionXxx to DubboSpringInitXxx

* Fix compile error

* fix tests
  • Loading branch information
kylixs committed Sep 17, 2021
1 parent 8a89d4d commit afbeaaf
Show file tree
Hide file tree
Showing 113 changed files with 1,826 additions and 741 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@
*/
package org.apache.dubbo.common.bytecode;

import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.ReflectUtils;

import javassist.ClassPool;
import javassist.CtMethod;
import org.apache.dubbo.common.utils.ClassUtils;
import org.apache.dubbo.common.utils.ReflectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.deploy;

import org.apache.dubbo.rpc.model.ScopeModel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

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;
import static org.apache.dubbo.common.deploy.DeployState.STARTING;
import static org.apache.dubbo.common.deploy.DeployState.STOPPED;
import static org.apache.dubbo.common.deploy.DeployState.STOPPING;

public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer<E> {

private volatile DeployState state = PENDING;

protected AtomicBoolean initialized = new AtomicBoolean(false);

private List<DeployListener<E>> listeners = new ArrayList<>();

private E scopeModel;

public AbstractDeployer(E scopeModel) {
this.scopeModel = scopeModel;
}

@Override
public boolean isPending() {
return state == PENDING;
}

@Override
public boolean isRunning() {
return state == STARTING || state == STARTED;
}

@Override
public boolean isStarted() {
return state == STARTED;
}

@Override
public boolean isStarting() {
return state == STARTING;
}

@Override
public boolean isStopping() {
return state == STOPPING;
}

@Override
public boolean isStopped() {
return state == STOPPED;
}

@Override
public boolean isFailed() {
return state == FAILED;
}

@Override
public DeployState getState() {
return state;
}

@Override
public void addDeployListener(DeployListener<E> listener) {
listeners.add(listener);
}

@Override
public void removeDeployListener(DeployListener<E> listener) {
listeners.remove(listener);
}

protected void setStarting() {
this.state = STARTING;
for (DeployListener<E> listener : listeners) {
listener.onStarting(scopeModel);
}
}

protected void setStarted() {
this.state = STARTED;
for (DeployListener<E> listener : listeners) {
listener.onStarted(scopeModel);
}
}
protected void setStopping() {
this.state = STOPPING;
for (DeployListener<E> listener : listeners) {
listener.onStopping(scopeModel);
}
}

protected void setStopped() {
this.state = STOPPED;
for (DeployListener<E> listener : listeners) {
listener.onStopped(scopeModel);
}
}

protected void setFailed(Throwable cause) {
this.state = FAILED;
for (DeployListener<E> listener : listeners) {
listener.onFailure(scopeModel, cause);
}
}

public boolean isInitialized() {
return initialized.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.qos.probe.impl;
package org.apache.dubbo.common.deploy;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.qos.probe.ReadinessProbe;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.rpc.model.ApplicationModel;

/**
* Listen for Dubbo application deployment events
*/
@SPI(scope = ExtensionScope.APPLICATION)
public interface ApplicationDeployListener extends DeployListener<ApplicationModel> {

@Activate
public class BootstrapReadinessProbe implements ReadinessProbe {
@Override
public boolean check() {
return !DubboBootstrap.getInstance().isShutdown() && DubboBootstrap.getInstance().isStartup();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,48 @@
package org.apache.dubbo.common.deploy;

import org.apache.dubbo.common.config.ReferenceCache;
import org.apache.dubbo.common.context.Lifecycle;
import org.apache.dubbo.rpc.model.ApplicationModel;

import java.util.concurrent.CompletableFuture;

/**
* initialize and start application instance
*/
public interface ApplicationDeployer extends Lifecycle {
public interface ApplicationDeployer extends Deployer<ApplicationModel> {

/**
* Initialize the component
*/
void initialize() throws IllegalStateException;

void initialize();
/**
* Starts the component.
*/
CompletableFuture start() throws IllegalStateException;

void start();
/**
* Stops the component.
*/
void stop() throws IllegalStateException;

void prepareApplicationInstance();

void destroy();

/**
* Indicates that the Application is initialized or not.
* @return
*/
boolean isInitialized();

boolean isStarted();
ApplicationModel getApplicationModel();

boolean isStartup();
ReferenceCache getReferenceCache();

boolean isShutdown();
boolean isAsync();

ApplicationModel getApplicationModel();
void checkStarting();

ReferenceCache getReferenceCache();
void checkStarted();

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.qos.probe.impl;
package org.apache.dubbo.common.deploy;

import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.qos.probe.StartupProbe;
import org.apache.dubbo.rpc.model.ScopeModel;

@Activate
public class BootstrapStartupProbe implements StartupProbe {
public interface DeployListener<E extends ScopeModel> {

void onStarting(E scopeModel);

void onStarted(E scopeModel);

void onStopping(E scopeModel);

void onStopped(E scopeModel);

void onFailure(E scopeModel, Throwable cause);

@Override
public boolean check() {
return DubboBootstrap.getInstance().isStartup();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.deploy;

import org.apache.dubbo.rpc.model.ScopeModel;

public class DeployListenerAdapter<E extends ScopeModel> implements DeployListener<E>{
@Override
public void onStarting(E scopeModel) {
}

@Override
public void onStarted(E scopeModel) {
}

@Override
public void onStopping(E scopeModel) {
}

@Override
public void onStopped(E scopeModel) {
}

@Override
public void onFailure(E scopeModel, Throwable cause) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.deploy;

/**
* Deploy state enum
*/
public enum DeployState {
PENDING, STARTING, STARTED, STOPPING, STOPPED, FAILED
}

0 comments on commit afbeaaf

Please sign in to comment.