2727import java .util .Map .Entry ;
2828import java .util .concurrent .ConcurrentHashMap ;
2929import java .util .concurrent .CopyOnWriteArrayList ;
30+ import java .util .concurrent .atomic .AtomicBoolean ;
3031import org .slf4j .Logger ;
3132import org .slf4j .LoggerFactory ;
3233
@@ -42,6 +43,7 @@ class SuperStreamProducer implements Producer {
4243 private final StreamEnvironment environment ;
4344 private final String name ;
4445 private final Metadata superStreamMetadata ;
46+ private final AtomicBoolean closed = new AtomicBoolean (false );
4547
4648 SuperStreamProducer (
4749 StreamProducerBuilder producerBuilder ,
@@ -91,36 +93,47 @@ public long getLastPublishingId() {
9193
9294 @ Override
9395 public void send (Message message , ConfirmationHandler confirmationHandler ) {
94- List <String > streams = this .routingStrategy .route (message , superStreamMetadata );
95- if (streams .isEmpty ()) {
96- confirmationHandler .handle (
97- new ConfirmationStatus (message , false , Constants .CODE_NO_ROUTE_FOUND ));
98- } else {
99- for (String stream : streams ) {
100- Producer producer =
101- producers .computeIfAbsent (
102- stream ,
103- stream1 -> {
104- Producer p =
105- producerBuilder .duplicate ().superStream (null ).stream (stream1 ).build ();
106- return p ;
107- });
108- producer .send (message , confirmationHandler );
96+ if (canSend ()) {
97+ List <String > streams = this .routingStrategy .route (message , superStreamMetadata );
98+ if (streams .isEmpty ()) {
99+ confirmationHandler .handle (
100+ new ConfirmationStatus (message , false , Constants .CODE_NO_ROUTE_FOUND ));
101+ } else {
102+ for (String stream : streams ) {
103+ Producer producer =
104+ producers .computeIfAbsent (
105+ stream ,
106+ stream1 -> {
107+ Producer p =
108+ producerBuilder .duplicate ().superStream (null ).stream (stream1 ).build ();
109+ return p ;
110+ });
111+ producer .send (message , confirmationHandler );
112+ }
109113 }
114+ } else {
115+ confirmationHandler .handle (
116+ new ConfirmationStatus (message , false , Constants .CODE_PRODUCER_CLOSED ));
110117 }
111118 }
112119
120+ private boolean canSend () {
121+ return !this .closed .get ();
122+ }
123+
113124 @ Override
114125 public void close () {
115- for (Entry <String , Producer > entry : producers .entrySet ()) {
116- try {
117- entry .getValue ().close ();
118- } catch (Exception e ) {
119- LOGGER .info (
120- "Error while closing producer for partition {} of super stream {}: {}" ,
121- entry .getKey (),
122- this .superStream ,
123- e .getMessage ());
126+ if (this .closed .compareAndSet (false , true )) {
127+ for (Entry <String , Producer > entry : producers .entrySet ()) {
128+ try {
129+ entry .getValue ().close ();
130+ } catch (Exception e ) {
131+ LOGGER .info (
132+ "Error while closing producer for partition {} of super stream {}: {}" ,
133+ entry .getKey (),
134+ this .superStream ,
135+ e .getMessage ());
136+ }
124137 }
125138 }
126139 }
0 commit comments