27
27
import java .util .Map .Entry ;
28
28
import java .util .concurrent .ConcurrentHashMap ;
29
29
import java .util .concurrent .CopyOnWriteArrayList ;
30
+ import java .util .concurrent .atomic .AtomicBoolean ;
30
31
import org .slf4j .Logger ;
31
32
import org .slf4j .LoggerFactory ;
32
33
@@ -42,6 +43,7 @@ class SuperStreamProducer implements Producer {
42
43
private final StreamEnvironment environment ;
43
44
private final String name ;
44
45
private final Metadata superStreamMetadata ;
46
+ private final AtomicBoolean closed = new AtomicBoolean (false );
45
47
46
48
SuperStreamProducer (
47
49
StreamProducerBuilder producerBuilder ,
@@ -91,36 +93,47 @@ public long getLastPublishingId() {
91
93
92
94
@ Override
93
95
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
+ }
109
113
}
114
+ } else {
115
+ confirmationHandler .handle (
116
+ new ConfirmationStatus (message , false , Constants .CODE_PRODUCER_CLOSED ));
110
117
}
111
118
}
112
119
120
+ private boolean canSend () {
121
+ return !this .closed .get ();
122
+ }
123
+
113
124
@ Override
114
125
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
+ }
124
137
}
125
138
}
126
139
}
0 commit comments