1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.infra.datasource.pool.destroyer;
19
20 import lombok.RequiredArgsConstructor;
21 import lombok.SneakyThrows;
22 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
23
24 import javax.sql.DataSource;
25 import java.sql.SQLException;
26 import java.util.Optional;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.Executors;
29
30
31
32
33 @RequiredArgsConstructor
34 public final class DataSourcePoolDestroyer {
35
36 private final DataSource dataSource;
37
38
39
40
41 public void asyncDestroy() {
42 if (!(dataSource instanceof AutoCloseable)) {
43 return;
44 }
45 ExecutorService executor = Executors.newSingleThreadExecutor();
46 executor.execute(this::graceDestroy);
47 executor.shutdown();
48 }
49
50 @SneakyThrows
51 private void graceDestroy() {
52 waitUntilActiveConnectionComplete();
53 ((AutoCloseable) dataSource).close();
54 }
55
56 private void waitUntilActiveConnectionComplete() throws SQLException {
57 Optional<DataSourcePoolActiveDetector> activeDetector = TypedSPILoader.findService(DataSourcePoolActiveDetector.class, dataSource.getClass().getName());
58 while (activeDetector.isPresent() && activeDetector.get().containsActiveConnection(dataSource)) {
59 try {
60 Thread.sleep(10L);
61 } catch (final InterruptedException ignore) {
62 Thread.currentThread().interrupt();
63 }
64 }
65 }
66 }