Skip to content

Commit ad728fa

Browse files
authored
feat(all):tune the sequence of resources closure (#5447)
1 parent 68b5faf commit ad728fa

43 files changed

Lines changed: 408 additions & 368 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

framework/src/main/java/org/tron/common/application/Application.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public interface Application {
3434

3535
void startServices();
3636

37+
// DO NOT USE THIS METHOD IN TEST CASES MAIN-THREAD
38+
default void blockUntilShutdown() {
39+
}
40+
3741
void shutdownServices();
3842

3943
void addService(Service service);

framework/src/main/java/org/tron/common/application/ApplicationImpl.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
import lombok.extern.slf4j.Slf4j;
44
import org.springframework.beans.factory.annotation.Autowired;
55
import org.springframework.stereotype.Component;
6-
import org.tron.common.logsfilter.EventPluginLoader;
76
import org.tron.common.parameter.CommonParameter;
87
import org.tron.core.ChainBaseManager;
98
import org.tron.core.config.args.Args;
10-
import org.tron.core.config.args.DynamicArgs;
119
import org.tron.core.consensus.ConsensusService;
1210
import org.tron.core.db.Manager;
1311
import org.tron.core.metrics.MetricsUtil;
@@ -31,9 +29,6 @@ public class ApplicationImpl implements Application {
3129
@Autowired
3230
private ConsensusService consensusService;
3331

34-
@Autowired
35-
private DynamicArgs dynamicArgs;
36-
3732
@Override
3833
public void setOptions(Args args) {
3934
// not used
@@ -64,35 +59,30 @@ public void startup() {
6459
}
6560
consensusService.start();
6661
MetricsUtil.init();
67-
dynamicArgs.init();
62+
this.initServices(Args.getInstance());
63+
this.startServices();
6864
}
6965

7066
@Override
7167
public void shutdown() {
72-
logger.info("******** start to shutdown ********");
68+
this.shutdownServices();
69+
consensusService.stop();
7370
if (!Args.getInstance().isSolidityNode() && (!Args.getInstance().p2pDisable)) {
7471
tronNetService.close();
7572
}
76-
consensusService.stop();
77-
synchronized (dbManager.getRevokingStore()) {
78-
dbManager.getSession().reset();
79-
closeRevokingStore();
80-
}
81-
dbManager.stopRePushThread();
82-
dbManager.stopRePushTriggerThread();
83-
EventPluginLoader.getInstance().stopPlugin();
84-
dbManager.stopFilterProcessThread();
85-
dbManager.stopValidateSignThread();
86-
getChainBaseManager().shutdown();
87-
dynamicArgs.close();
88-
logger.info("******** end to shutdown ********");
73+
dbManager.close();
8974
}
9075

9176
@Override
9277
public void startServices() {
9378
services.start();
9479
}
9580

81+
@Override
82+
public void blockUntilShutdown() {
83+
services.blockUntilShutdown();
84+
}
85+
9686
@Override
9787
public void shutdownServices() {
9888
services.stop();
@@ -108,9 +98,4 @@ public ChainBaseManager getChainBaseManager() {
10898
return chainBaseManager;
10999
}
110100

111-
private void closeRevokingStore() {
112-
logger.info("******** start to closeRevokingStore ********");
113-
dbManager.getRevokingStore().shutdown();
114-
}
115-
116101
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* java-tron is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* java-tron is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
package org.tron.common.application;
17+
18+
import com.google.common.base.Objects;
19+
import lombok.extern.slf4j.Slf4j;
20+
import org.eclipse.jetty.server.Server;
21+
22+
@Slf4j(topic = "rpc")
23+
public abstract class HttpService implements Service {
24+
25+
protected Server apiServer;
26+
protected int port;
27+
28+
@Override
29+
public void blockUntilShutdown() {
30+
if (apiServer != null) {
31+
try {
32+
apiServer.join();
33+
} catch (InterruptedException e) {
34+
logger.warn("{}", e.getMessage());
35+
Thread.currentThread().interrupt();
36+
}
37+
}
38+
}
39+
40+
@Override
41+
public void start() {
42+
if (apiServer != null) {
43+
try {
44+
apiServer.start();
45+
logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port);
46+
} catch (Exception e) {
47+
logger.error("{}", this.getClass().getSimpleName(), e);
48+
}
49+
}
50+
}
51+
52+
@Override
53+
public void stop() {
54+
if (apiServer != null) {
55+
logger.info("{} shutdown...", this.getClass().getSimpleName());
56+
try {
57+
apiServer.stop();
58+
} catch (Exception e) {
59+
logger.warn("{}", this.getClass().getSimpleName(), e);
60+
}
61+
logger.info("{} shutdown complete", this.getClass().getSimpleName());
62+
}
63+
}
64+
65+
@Override
66+
public boolean equals(Object o) {
67+
if (this == o) {
68+
return true;
69+
}
70+
if (o == null || getClass() != o.getClass()) {
71+
return false;
72+
}
73+
HttpService that = (HttpService) o;
74+
return port == that.port;
75+
}
76+
77+
@Override
78+
public int hashCode() {
79+
return Objects.hashCode(getClass().getSimpleName(), port);
80+
}
81+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* java-tron is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* java-tron is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
package org.tron.common.application;
17+
18+
import com.google.common.base.Objects;
19+
import io.grpc.Server;
20+
import java.io.IOException;
21+
import java.util.concurrent.TimeUnit;
22+
import lombok.extern.slf4j.Slf4j;
23+
24+
@Slf4j(topic = "rpc")
25+
public abstract class RpcService implements Service {
26+
27+
protected Server apiServer;
28+
protected int port;
29+
30+
@Override
31+
public void blockUntilShutdown() {
32+
if (apiServer != null) {
33+
try {
34+
apiServer.awaitTermination();
35+
} catch (InterruptedException e) {
36+
logger.warn("{}", e.getMessage());
37+
Thread.currentThread().interrupt();
38+
}
39+
}
40+
}
41+
42+
@Override
43+
public void start() {
44+
if (apiServer != null) {
45+
try {
46+
apiServer.start();
47+
logger.info("{} started, listening on {}", this.getClass().getSimpleName(), port);
48+
} catch (IOException e) {
49+
logger.error("{}", this.getClass().getSimpleName(), e);
50+
}
51+
}
52+
}
53+
54+
@Override
55+
public void stop() {
56+
if (apiServer != null) {
57+
logger.info("{} shutdown...", this.getClass().getSimpleName());
58+
try {
59+
apiServer.shutdown().awaitTermination(5, TimeUnit.SECONDS);
60+
} catch (InterruptedException e) {
61+
Thread.currentThread().interrupt();
62+
logger.warn("{}", this.getClass().getSimpleName(), e);
63+
}
64+
logger.info("{} shutdown complete", this.getClass().getSimpleName());
65+
}
66+
}
67+
68+
@Override
69+
public boolean equals(Object o) {
70+
if (this == o) {
71+
return true;
72+
}
73+
if (o == null || getClass() != o.getClass()) {
74+
return false;
75+
}
76+
RpcService that = (RpcService) o;
77+
return port == that.port;
78+
}
79+
80+
@Override
81+
public int hashCode() {
82+
return Objects.hashCode(getClass().getSimpleName(), port);
83+
}
84+
85+
}

framework/src/main/java/org/tron/common/application/Service.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ public interface Service {
2323

2424
void init(CommonParameter parameter);
2525

26+
/**
27+
* Start the service.
28+
* {@link Service#init(CommonParameter parameter) init(CommonParameter parameter)} must be called
29+
* before this method.
30+
*/
2631
void start();
2732

2833
void stop();
34+
35+
void blockUntilShutdown();
2936
}

framework/src/main/java/org/tron/common/application/ServiceContainer.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@
1515

1616
package org.tron.common.application;
1717

18-
import java.util.ArrayList;
18+
import java.util.Collections;
19+
import java.util.LinkedHashSet;
20+
import java.util.Set;
1921
import lombok.extern.slf4j.Slf4j;
2022
import org.tron.common.parameter.CommonParameter;
2123

2224
@Slf4j(topic = "app")
2325
public class ServiceContainer {
2426

25-
private ArrayList<Service> services;
27+
private final Set<Service> services;
2628

2729
public ServiceContainer() {
28-
this.services = new ArrayList<>();
30+
this.services = Collections.synchronizedSet(new LinkedHashSet<>());
2931
}
3032

3133
public void add(Service service) {
@@ -34,31 +36,38 @@ public void add(Service service) {
3436

3537

3638
public void init() {
37-
for (Service service : this.services) {
39+
this.services.forEach(service -> {
3840
logger.debug("Initing {}.", service.getClass().getSimpleName());
3941
service.init();
40-
}
42+
});
4143
}
4244

4345
public void init(CommonParameter parameter) {
44-
for (Service service : this.services) {
46+
this.services.forEach(service -> {
4547
logger.debug("Initing {}.", service.getClass().getSimpleName());
4648
service.init(parameter);
47-
}
49+
});
4850
}
4951

5052
public void start() {
51-
logger.debug("Starting services.");
52-
for (Service service : this.services) {
53+
logger.info("Starting api services.");
54+
this.services.forEach(service -> {
5355
logger.debug("Starting {}.", service.getClass().getSimpleName());
5456
service.start();
55-
}
57+
});
58+
logger.info("All api services started.");
5659
}
5760

5861
public void stop() {
59-
for (Service service : this.services) {
62+
logger.info("Stopping api services.");
63+
this.services.forEach(service -> {
6064
logger.debug("Stopping {}.", service.getClass().getSimpleName());
6165
service.stop();
62-
}
66+
});
67+
logger.info("All api services stopped.");
68+
}
69+
70+
public void blockUntilShutdown() {
71+
this.services.stream().findFirst().ifPresent(Service::blockUntilShutdown);
6372
}
6473
}

framework/src/main/java/org/tron/common/application/TronApplicationContext.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
44
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
5-
import org.tron.program.FullNode;
5+
import org.tron.core.config.TronLogShutdownHook;
66

77
public class TronApplicationContext extends AnnotationConfigApplicationContext {
88

@@ -25,10 +25,15 @@ public TronApplicationContext(String... basePackages) {
2525
public void doClose() {
2626
logger.info("******** start to close ********");
2727
Application appT = ApplicationFactory.create(this);
28-
appT.shutdownServices();
2928
appT.shutdown();
3029
super.doClose();
3130
logger.info("******** close end ********");
32-
FullNode.shutDownSign = true;
31+
TronLogShutdownHook.shutDown = true;
32+
}
33+
34+
@Override
35+
public void registerShutdownHook() {
36+
super.registerShutdownHook();
37+
TronLogShutdownHook.shutDown = false;
3338
}
3439
}

framework/src/main/java/org/tron/core/config/DefaultConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public DefaultConfig() {
4242
Thread.setDefaultUncaughtExceptionHandler((t, e) -> logger.error("Uncaught exception", e));
4343
}
4444

45-
@Bean
45+
@Bean(destroyMethod = "")
4646
public RevokingDatabase revokingDatabase() {
4747
try {
4848
return new SnapshotManager(

framework/src/main/java/org/tron/core/config/TronLogShutdownHook.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ public class TronLogShutdownHook extends ShutdownHookBase {
2020
*/
2121
private final long check_times = 60 * 1000 / CHECK_SHUTDOWN_DELAY.getMilliseconds();
2222

23+
// if true, shutdown hook will be executed , for example, 'java -jar FullNode.jar -[v|h]'.
24+
public static volatile boolean shutDown = true;
25+
2326
public TronLogShutdownHook() {
2427
}
2528

2629
@Override
2730
public void run() {
2831
try {
2932
for (int i = 0; i < check_times; i++) {
30-
if (FullNode.shutDownSign) {
33+
if (shutDown) {
3134
break;
3235
}
3336
addInfo("Sleeping for " + CHECK_SHUTDOWN_DELAY);

0 commit comments

Comments
 (0)