33import static org .junit .Assert .*;
44import static org .junit .Assume .*;
55
6+ import io .grpc .CallOptions ;
7+ import io .grpc .Channel ;
8+ import io .grpc .ClientCall ;
9+ import io .grpc .ClientInterceptor ;
10+ import io .grpc .ForwardingClientCall ;
11+ import io .grpc .MethodDescriptor ;
612import io .temporal .activity .ActivityOptions ;
713import io .temporal .api .history .v1 .HistoryEvent ;
14+ import io .temporal .api .workflowservice .v1 .RespondWorkflowTaskCompletedRequest ;
15+ import io .temporal .api .workflowservice .v1 .WorkflowServiceGrpc ;
816import io .temporal .client .WorkflowClient ;
917import io .temporal .client .WorkflowOptions ;
1018import io .temporal .client .WorkflowStub ;
1119import io .temporal .common .WorkflowExecutionHistory ;
1220import io .temporal .internal .Config ;
21+ import io .temporal .serviceclient .WorkflowServiceStubsOptions ;
1322import io .temporal .testUtils .CountingSlotSupplier ;
1423import io .temporal .testing .TestWorkflowEnvironment ;
1524import io .temporal .testing .internal .ExternalServiceTestConfigurator ;
2332import io .temporal .workflow .shared .TestActivities .TestActivitiesImpl ;
2433import java .time .Duration ;
2534import java .util .ArrayList ;
35+ import java .util .Collections ;
2636import java .util .Set ;
2737import java .util .concurrent .TimeUnit ;
38+ import java .util .concurrent .atomic .AtomicInteger ;
2839import java .util .stream .Collectors ;
2940import org .junit .*;
3041
3142public class EagerActivityDispatchingTest {
3243 private static final String TASK_QUEUE = "test-eager-activity-dispatch" ;
3344 private TestWorkflowEnvironment env ;
3445 private ArrayList <WorkerFactory > workerFactories ;
46+ private final EagerActivityRequestInterceptor eagerActivityRequestInterceptor =
47+ new EagerActivityRequestInterceptor ();
3548
3649 private final TestActivitiesImpl activitiesImpl = new TestActivitiesImpl ();
3750 CountingSlotSupplier <WorkflowSlotInfo > workflowTaskSlotSupplier = new CountingSlotSupplier <>(100 );
@@ -42,9 +55,16 @@ public class EagerActivityDispatchingTest {
4255
4356 @ Before
4457 public void setUp () throws Exception {
58+ eagerActivityRequestInterceptor .reset ();
4559 this .env =
4660 TestWorkflowEnvironment .newInstance (
47- ExternalServiceTestConfigurator .configuredTestEnvironmentOptions ().build ());
61+ ExternalServiceTestConfigurator .configuredTestEnvironmentOptions ()
62+ .setWorkflowServiceStubsOptions (
63+ WorkflowServiceStubsOptions .newBuilder ()
64+ .setGrpcClientInterceptors (
65+ Collections .singletonList (eagerActivityRequestInterceptor ))
66+ .build ())
67+ .build ());
4868 this .workerFactories = new ArrayList <>();
4969 }
5070
@@ -125,6 +145,25 @@ public void testEagerActivities() {
125145 assertFalse (activityTaskStartedEventIdentity .contains ("worker2" ));
126146 }
127147
148+ @ Test
149+ public void testMaxEagerActivityReservationsPerWorkflowTask () {
150+ setupWorker (
151+ "worker1" ,
152+ WorkerOptions .newBuilder ()
153+ .setMaxEagerActivityReservationsPerWorkflowTask (2 )
154+ .setDisableEagerExecution (false ),
155+ true );
156+
157+ EagerActivityTestWorkflow workflowStub =
158+ env .getWorkflowClient ()
159+ .newWorkflowStub (
160+ EagerActivityTestWorkflow .class ,
161+ WorkflowOptions .newBuilder ().setTaskQueue (TASK_QUEUE ).build ());
162+ workflowStub .execute (true );
163+
164+ assertEquals (2 , eagerActivityRequestInterceptor .getEagerActivityRequestCount ());
165+ }
166+
128167 @ Test
129168 public void testNoEagerActivitiesIfDisabledOnWorker () {
130169 assumeTrue (
@@ -222,4 +261,50 @@ public void execute(boolean enableEagerActivityDispatch) {
222261 Promise .allOf (promises ).get ();
223262 }
224263 }
264+
265+ private static class EagerActivityRequestInterceptor implements ClientInterceptor {
266+ private final AtomicInteger eagerActivityRequestCount = new AtomicInteger (-1 );
267+
268+ @ Override
269+ public <ReqT , RespT > ClientCall <ReqT , RespT > interceptCall (
270+ MethodDescriptor <ReqT , RespT > method , CallOptions callOptions , Channel next ) {
271+ if (method == WorkflowServiceGrpc .getRespondWorkflowTaskCompletedMethod ()) {
272+ return new ForwardingClientCall .SimpleForwardingClientCall <ReqT , RespT >(
273+ next .newCall (method , callOptions )) {
274+ @ Override
275+ public void sendMessage (ReqT message ) {
276+ RespondWorkflowTaskCompletedRequest request =
277+ (RespondWorkflowTaskCompletedRequest ) message ;
278+ long activityCommandCount =
279+ request .getCommandsList ().stream ()
280+ .filter (command -> command .hasScheduleActivityTaskCommandAttributes ())
281+ .count ();
282+ if (activityCommandCount > 0 ) {
283+ int eagerRequestCount =
284+ (int )
285+ request .getCommandsList ().stream ()
286+ .filter (command -> command .hasScheduleActivityTaskCommandAttributes ())
287+ .filter (
288+ command ->
289+ command
290+ .getScheduleActivityTaskCommandAttributes ()
291+ .getRequestEagerExecution ())
292+ .count ();
293+ eagerActivityRequestCount .compareAndSet (-1 , eagerRequestCount );
294+ }
295+ super .sendMessage (message );
296+ }
297+ };
298+ }
299+ return next .newCall (method , callOptions );
300+ }
301+
302+ int getEagerActivityRequestCount () {
303+ return eagerActivityRequestCount .get ();
304+ }
305+
306+ void reset () {
307+ eagerActivityRequestCount .set (-1 );
308+ }
309+ }
225310}
0 commit comments