|
23 | 23 | import org.elasticsearch.core.IOUtils; |
24 | 24 |
|
25 | 25 | import java.io.Closeable; |
| 26 | +import java.util.ArrayList; |
26 | 27 | import java.util.Collections; |
27 | 28 | import java.util.HashMap; |
| 29 | +import java.util.List; |
28 | 30 | import java.util.Map; |
29 | 31 | import java.util.concurrent.ConcurrentHashMap; |
| 32 | +import java.util.concurrent.Executor; |
30 | 33 | import java.util.concurrent.atomic.AtomicBoolean; |
31 | 34 | import java.util.function.Function; |
32 | 35 |
|
33 | 36 | public class S3PerProjectClientManager implements ClusterStateListener { |
34 | 37 |
|
35 | 38 | private final Settings settings; |
36 | 39 | private final Function<S3ClientSettings, AmazonS3> clientBuilder; |
| 40 | + private final Executor executor; |
37 | 41 | // A map of projectId to clients holder. Adding to and removing from the map happen only with the cluster state listener thread. |
38 | 42 | private final Map<ProjectId, ClientsHolder> perProjectClientsCache; |
39 | 43 |
|
40 | | - public S3PerProjectClientManager(Settings settings, Function<S3ClientSettings, AmazonS3> clientBuilder) { |
| 44 | + public S3PerProjectClientManager(Settings settings, Function<S3ClientSettings, AmazonS3> clientBuilder, Executor executor) { |
41 | 45 | this.settings = settings; |
42 | 46 | this.clientBuilder = clientBuilder; |
| 47 | + this.executor = executor; |
43 | 48 | this.perProjectClientsCache = new ConcurrentHashMap<>(); |
44 | 49 | } |
45 | 50 |
|
@@ -70,22 +75,25 @@ public void clusterChanged(ClusterChangedEvent event) { |
70 | 75 | } |
71 | 76 | } |
72 | 77 |
|
| 78 | + final List<ClientsHolder> clientsHoldersToClose = new ArrayList<>(); |
73 | 79 | // Updated projects |
74 | 80 | for (var projectId : updatedPerProjectClients.keySet()) { |
75 | 81 | final var old = perProjectClientsCache.put(projectId, updatedPerProjectClients.get(projectId)); |
76 | 82 | if (old != null) { |
77 | | - old.close(); |
| 83 | + clientsHoldersToClose.add(old); |
78 | 84 | } |
79 | 85 | } |
80 | | - |
81 | 86 | // removed projects |
82 | 87 | for (var projectId : perProjectClientsCache.keySet()) { |
83 | 88 | if (currentProjects.containsKey(projectId) == false) { |
84 | 89 | final var removed = perProjectClientsCache.remove(projectId); |
85 | 90 | assert removed != null; |
86 | | - removed.close(); |
| 91 | + clientsHoldersToClose.add(removed); |
87 | 92 | } |
88 | 93 | } |
| 94 | + if (clientsHoldersToClose.isEmpty() == false) { |
| 95 | + executor.execute(() -> IOUtils.closeWhileHandlingException(clientsHoldersToClose)); |
| 96 | + } |
89 | 97 | } |
90 | 98 |
|
91 | 99 | public AmazonS3Reference client(ProjectId projectId, RepositoryMetadata repositoryMetadata) { |
|
0 commit comments