16
16
import java .net .SocketAddress ;
17
17
import java .util .Optional ;
18
18
import java .util .concurrent .CompletableFuture ;
19
+ import java .util .concurrent .ConcurrentHashMap ;
19
20
import java .util .concurrent .atomic .AtomicBoolean ;
20
21
import lombok .extern .slf4j .Slf4j ;
21
22
import org .apache .pulsar .broker .PulsarService ;
@@ -41,14 +42,14 @@ public class KafkaTopicManager {
41
42
42
43
private final AtomicBoolean closed = new AtomicBoolean (false );
43
44
44
- KafkaTopicManager (KafkaRequestHandler kafkaRequestHandler ) {
45
+ KafkaTopicManager (KafkaRequestHandler kafkaRequestHandler , KafkaTopicLookupService kafkaTopicLookupService ) {
45
46
this .requestHandler = kafkaRequestHandler ;
46
47
PulsarService pulsarService = kafkaRequestHandler .getPulsarService ();
47
48
this .brokerService = pulsarService .getBrokerService ();
48
49
this .internalServerCnx = new InternalServerCnx (requestHandler );
49
50
this .lookupClient = kafkaRequestHandler .getLookupClient ();
50
- this .kafkaTopicLookupService = new KafkaTopicLookupService ( pulsarService . getBrokerService ()) ;
51
- }
51
+ this .kafkaTopicLookupService = kafkaTopicLookupService ;
52
+ }
52
53
53
54
// update Ctx information, since at internalServerCnx create time there is no ctx passed into kafkaRequestHandler.
54
55
public void setRemoteAddress (SocketAddress remoteAddress ) {
@@ -101,12 +102,12 @@ public CompletableFuture<KafkaTopicConsumerManager> getTopicConsumerManager(Stri
101
102
102
103
private Producer registerInPersistentTopic (PersistentTopic persistentTopic ) {
103
104
Producer producer = new InternalProducer (persistentTopic , internalServerCnx ,
104
- lookupClient .getPulsarClient ().newRequestId (),
105
- brokerService .generateUniqueProducerName ());
105
+ lookupClient .getPulsarClient ().newRequestId (),
106
+ brokerService .generateUniqueProducerName ());
106
107
107
108
if (log .isDebugEnabled ()) {
108
109
log .debug ("[{}] Register Mock Producer {} into PersistentTopic {}" ,
109
- requestHandler .ctx .channel (), producer , persistentTopic .getName ());
110
+ requestHandler .ctx .channel (), producer , persistentTopic .getName ());
110
111
}
111
112
112
113
// this will register and add USAGE_COUNT_UPDATER.
@@ -122,8 +123,9 @@ public Optional<Producer> registerProducerInPersistentTopic(String topicName, Pe
122
123
}
123
124
return Optional .empty ();
124
125
}
125
- return Optional .of (requestHandler .getKafkaTopicManagerSharedState ()
126
- .getReferences ().computeIfAbsent (topicName , (__ ) -> registerInPersistentTopic (persistentTopic )));
126
+ ConcurrentHashMap <String , Producer > references = requestHandler
127
+ .getKafkaTopicManagerSharedState ().getReferences ();
128
+ return Optional .of (references .computeIfAbsent (topicName , (__ ) -> registerInPersistentTopic (persistentTopic )));
127
129
}
128
130
129
131
// when channel close, release all the topics reference in persistentTopic
@@ -141,18 +143,23 @@ public void close() {
141
143
}
142
144
143
145
public CompletableFuture <Optional <PersistentTopic >> getTopic (String topicName ) {
144
- if (closed .get ()) {
145
- if (log .isDebugEnabled ()) {
146
- log .debug ("[{}] Return null for getTopic({}) since channel is closing" ,
147
- requestHandler .ctx .channel (), topicName );
146
+ try {
147
+ if (closed .get ()) {
148
+ if (log .isDebugEnabled ()) {
149
+ log .debug ("[{}] Return null for getTopic({}) since channel is closing" ,
150
+ requestHandler .ctx .channel (), topicName );
151
+ }
152
+ return CompletableFuture .completedFuture (Optional .empty ());
148
153
}
154
+ CompletableFuture <Optional <PersistentTopic >> topicCompletableFuture =
155
+ kafkaTopicLookupService .getTopic (topicName , requestHandler .ctx .channel ());
156
+ // cache for removing producer
157
+ requestHandler .getKafkaTopicManagerSharedState ().getTopics ().put (topicName , topicCompletableFuture );
158
+ return topicCompletableFuture ;
159
+ } catch (Throwable error ) {
160
+ log .error ("Unhandled error for {}" , topicName , error );
149
161
return CompletableFuture .completedFuture (Optional .empty ());
150
162
}
151
- CompletableFuture <Optional <PersistentTopic >> topicCompletableFuture =
152
- kafkaTopicLookupService .getTopic (topicName , requestHandler .ctx .channel ());
153
- // cache for removing producer
154
- requestHandler .getKafkaTopicManagerSharedState ().getTopics ().put (topicName , topicCompletableFuture );
155
- return topicCompletableFuture ;
156
163
}
157
164
158
165
public void invalidateCacheForFencedManagerLedgerOnTopic (String fullTopicName ) {
0 commit comments