|
19 | 19 | import java.io.IOException; |
20 | 20 | import java.io.InputStream; |
21 | 21 | import java.net.InetAddress; |
22 | | -import java.net.UnknownHostException; |
23 | 22 | import java.util.Date; |
24 | 23 | import java.util.HashSet; |
25 | 24 | import java.util.Map; |
26 | 25 | import java.util.Properties; |
27 | 26 | import java.util.Set; |
28 | 27 | import java.util.concurrent.ConcurrentHashMap; |
| 28 | +import java.util.concurrent.Executors; |
| 29 | +import java.util.concurrent.ExecutorService; |
| 30 | +import java.util.concurrent.TimeUnit; |
| 31 | +import java.net.UnknownHostException; |
| 32 | +import software.amazon.awssdk.services.dynamodb.DynamoDbClient; |
| 33 | +import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest; |
| 34 | +import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse; |
| 35 | +import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest; |
29 | 36 |
|
30 | 37 | public class Consumers { |
31 | 38 |
|
@@ -149,6 +156,16 @@ private void reconfigureConsumers(Set<String> newRules, Set<String> currentRules |
149 | 156 | log.error(e.getMessage(), e); |
150 | 157 | } |
151 | 158 |
|
| 159 | + // Optionally add dynamic suffix to the KCL application name |
| 160 | + if (kinesisConfig.isAppNameDynamicSuffixEnabled()) { |
| 161 | + String suffix = resolveDynamicSuffix(kinesisConfig.getAppNameDynamicSuffixFormat()); |
| 162 | + kinesisApplicationName = kinesisApplicationName + suffix; |
| 163 | + // Optionally kick off async cleanup of old lease tables |
| 164 | + if (kinesisConfig.isCleanupOldLeaseTablesEnabled()) { |
| 165 | + asyncCleanupOldLeaseTables(getKinesisApplicationName(kinesisStreamName, hostName, carbonjEnv)); |
| 166 | + } |
| 167 | + } |
| 168 | + |
152 | 169 | Counter initRetryCounter = metricRegistry.counter(MetricRegistry.name("kinesis.consumer." + kinesisStreamName + ".initRetryCounter")); |
153 | 170 | KinesisConsumer kinesisConsumer = new KinesisConsumer(metricRegistry, pointProcessor, recoveryPointProcessor, kinesisStreamName, |
154 | 171 | kinesisApplicationName, kinesisConfig, checkPointMgr, initRetryCounter, kinesisConsumerRegion, kinesisConsumerTracebackMinutes); |
@@ -185,6 +202,50 @@ private String getKinesisApplicationName(String streamName, String hostName, Str |
185 | 202 | return streamName + "-" + hostName + "-" + carbonjEnv; |
186 | 203 | } |
187 | 204 |
|
| 205 | + private String resolveDynamicSuffix(String format) { |
| 206 | + String suffix = format; |
| 207 | + try { |
| 208 | + suffix = suffix.replace("{epoch}", Long.toString(System.currentTimeMillis())) |
| 209 | + .replace("{hostname}", InetAddress.getLocalHost().getHostName()) |
| 210 | + .replace("{uuid}", java.util.UUID.randomUUID().toString()); |
| 211 | + } catch (Throwable t) { |
| 212 | + // fallback minimal suffix |
| 213 | + suffix = "-" + System.currentTimeMillis(); |
| 214 | + } |
| 215 | + if (!suffix.startsWith("-")) { |
| 216 | + suffix = "-" + suffix; |
| 217 | + } |
| 218 | + return suffix; |
| 219 | + } |
| 220 | + |
| 221 | + private void asyncCleanupOldLeaseTables(String baseApplicationName) { |
| 222 | + ExecutorService es = Executors.newSingleThreadExecutor(r -> { |
| 223 | + Thread t = new Thread(r, "kcl-lease-cleanup"); |
| 224 | + t.setDaemon(true); |
| 225 | + return t; |
| 226 | + }); |
| 227 | + es.submit(() -> { |
| 228 | + try (DynamoDbClient ddb = DynamoDbClient.builder().build()) { |
| 229 | + ListTablesResponse resp = ddb.listTables(ListTablesRequest.builder().build()); |
| 230 | + for (String table : resp.tableNames()) { |
| 231 | + // KCL v2/v3 table name prefix is usually application name; be conservative |
| 232 | + if (table.startsWith(baseApplicationName) && !table.equals(baseApplicationName)) { |
| 233 | + try { |
| 234 | + ddb.deleteTable(DeleteTableRequest.builder().tableName(table).build()); |
| 235 | + log.info("Submitted async deletion for old KCL lease/checkpoint table {}", table); |
| 236 | + } catch (Throwable t) { |
| 237 | + log.warn("Failed to delete table {}: {}", table, t.getMessage()); |
| 238 | + } |
| 239 | + } |
| 240 | + } |
| 241 | + } catch (Throwable t) { |
| 242 | + log.warn("KCL lease cleanup encountered an error: {}", t.getMessage()); |
| 243 | + } |
| 244 | + }); |
| 245 | + es.shutdown(); |
| 246 | + try { es.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException ignored) {} |
| 247 | + } |
| 248 | + |
188 | 249 | private void close(Set<String> consumerSet) { |
189 | 250 | if (null == consumerSet) { |
190 | 251 | return; |
|
0 commit comments