I am performing load testing in the cadence cluster.
I am using version 3.12.0 in a Spring Boot Application.
My load tests consist of two groups of requests:
- 100 delayed requests, something between 0.5-1 second per request
- 100 parallel requests
The delayed requests are working perfectly, but the parallel requests are not.
The workflow has just one type of activity that is used n times, where n is the size of a list of Process
. These Process
are configured in the application.properties and there are 4 types of lists.
The whole idea of the workflow is:
-
an endpoint triggers the workflow to start
-
then it captures the list of processes and then the workflow awaits a signal
-
an external application triggers the signal and then the loop of size n begins.
-
inside the loop, a message is sent to a queue and awaits a signal to send another message.
- an external application will process the message and then send the signal for the workflow to continue.
-
after the list is fully processed, the workflow ends.
Here it is some samples of the Activity and Workflow:
// activity interface
public interface ISendMessageActivity {
@ActivityMethod(scheduleToCloseTimeoutSeconds = 60 * 60)
void sendMessage(Params params);
}
// activity implementation
@RequiredArgsConstructor
@Component
@Scope("prototype")
@Slf4j
public class SendMessageActivityImpl implements ISendMessageActivity {
private final QueueService queueService;
@Override
public void sendMessage(Params params) {
var messageParams = new MessageParams();
messageParams.setId(String.valueOf(Instant.now().getNano()));
messageParams.setParams(params);
queueService.requestProcess(params);
}
}
// workflow interface
public interface IPublishingWorkflow {
@WorkflowMethod(executionStartToCloseTimeoutSeconds = 60 * 60)
void startWorkflow(Params params);
@SignalMethod
void continueWorkflow();
}
// workflow implementation
@Component
@Scope("request")
@Slf4j
public class PublishingWorkflowImpl implements IPublishingWorkflow {
@Getter @Setter
private int processNumber = 0;
@Getter @Setter
private int before;
private final ProcessConfiguration processConfiguration;
private final ISendMessageActivity sendMessageActivities;
public PublishingWorkflowImpl() {
this.processConfiguration = SpringContext.getBeans(ProcessConfiguration.class);
this.sendMessageActivities = Workflow.newActivityStub(ISendMessageActivity.class);
}
@Override
public void startWorkflow(Params params) {
List<Process> processes = getProcesses(params);
processNumber++;
setBefore(processNumber);
Workflow.await(() -> processNumber > before);
for (Process process : processes) {
params.setProcess(process);
sendMessageActivities.sendMessage(params);
before = processNumber;
Workflow.await(() -> processNumber > before);
}
log.info("Workflow finished. {}", params.getPublishId());
}
@Override
public void continueWorkflow() {
setProcessNumber(getProcessNumber() + 1);
}
private List<Process> getProcesses(Params params) {
//
}
}
I isolated the creation of the WorkflowClient so that there is only one instance while the application is active. This reduced CPU and memory consumption, but did not solve the issue of parallel requests.
I changed the scope of the workflow implementation to “singleton” but it led to other problems.
Am I missing some uber-cadence concept?