6161import java .util .Set ;
6262import java .util .UUID ;
6363import java .util .concurrent .ConcurrentHashMap ;
64+ import java .util .concurrent .Executor ;
65+ import java .util .concurrent .ExecutorService ;
6466import java .util .concurrent .ScheduledExecutorService ;
6567import java .util .concurrent .TimeUnit ;
6668import java .util .concurrent .atomic .AtomicBoolean ;
@@ -97,6 +99,7 @@ final class StreamingSubscriberConnection extends AbstractApiService implements
9799 private final String subscription ;
98100 private final SubscriptionName subscriptionNameObject ;
99101 private final ScheduledExecutorService systemExecutor ;
102+ private final ExecutorService eodAckCallbackExecutor ;
100103 private final MessageDispatcher messageDispatcher ;
101104
102105 private final FlowControlSettings flowControlSettings ;
@@ -128,6 +131,7 @@ private StreamingSubscriberConnection(Builder builder) {
128131 subscription = builder .subscription ;
129132 subscriptionNameObject = SubscriptionName .parse (builder .subscription );
130133 systemExecutor = builder .systemExecutor ;
134+ eodAckCallbackExecutor = builder .eodAckCallbackExecutor ;
131135
132136 // We need to set the default stream ack deadline on the initial request, this will be
133137 // updated by modack requests in the message dispatcher
@@ -455,7 +459,7 @@ private void sendAckOperations(
455459 .setSubscription (subscription )
456460 .addAllAckIds (ackIdsInRequest )
457461 .build ());
458- ApiFutures .addCallback (ackFuture , callback , directExecutor ());
462+ ApiFutures .addCallback (ackFuture , callback , getCallbackExecutor ());
459463 pendingOperations ++;
460464 }
461465 ackOperationsWaiter .incrementPendingCount (pendingOperations );
@@ -504,7 +508,7 @@ private void sendModackOperations(
504508 .addAllAckIds (ackIdsInRequest )
505509 .setAckDeadlineSeconds (modackRequestData .getDeadlineExtensionSeconds ())
506510 .build ());
507- ApiFutures .addCallback (modackFuture , callback , directExecutor ());
511+ ApiFutures .addCallback (modackFuture , callback , getCallbackExecutor ());
508512 pendingOperations ++;
509513 }
510514 }
@@ -716,6 +720,13 @@ public void run() {
716720 };
717721 }
718722
723+ private Executor getCallbackExecutor () {
724+ if (!getExactlyOnceDeliveryEnabled ()) {
725+ return directExecutor ();
726+ }
727+ return eodAckCallbackExecutor ;
728+ }
729+
719730 /** Builder of {@link StreamingSubscriberConnection StreamingSubscriberConnections}. */
720731 public static final class Builder {
721732 private MessageReceiver receiver ;
@@ -736,6 +747,7 @@ public static final class Builder {
736747 private boolean useLegacyFlowControl ;
737748 private ScheduledExecutorService executor ;
738749 private ScheduledExecutorService systemExecutor ;
750+ private ExecutorService eodAckCallbackExecutor ;
739751 private ApiClock clock ;
740752
741753 private boolean enableOpenTelemetryTracing ;
@@ -826,6 +838,11 @@ public Builder setSystemExecutor(ScheduledExecutorService systemExecutor) {
826838 return this ;
827839 }
828840
841+ public Builder setEodAckCallbackExecutor (ExecutorService eodAckCallbackExecutor ) {
842+ this .eodAckCallbackExecutor = eodAckCallbackExecutor ;
843+ return this ;
844+ }
845+
829846 public Builder setClock (ApiClock clock ) {
830847 this .clock = clock ;
831848 return this ;
0 commit comments