In a process ( Aysnc) , I created a service task with Java Delegate . In delegate , we are making REST API and this call is long running call like we get the response after 15 mins…
Service Task → Java Delegate → Rest API
When this process is started , the Java Delegate triggers the Rest API call and when this is still running and after around 6 minutes we see another thread starting and this in turn calls this service( java delegate) again . After next 6 mins , another new thread triggers this service task again. So, at client side we are multiple requests.
To resolve this issue, we were considering the options below , however not sure if this resolves the issue.
Convert the Rest API call to Asyn in Java delegate
External Task
Please suggest if there are any other solutions to resolve this issue.
the Delegate is not meant to execute long running calls sync. The behaviour you can see is that the job times out and gets picked up again by another thread (job executor).
My suggestion would be to use the External Task for these durations of task execution. Here, you can start with an initial lock of some minutes and extend the lock while waiting for the answer.
The other option would be the implementation of a async pattern with Message send/receive tasks or events. This would also work. Important is here that the engine is not “blocked” by a thread waiting for the answer but the wait state is modelled and saved to the database of the process engine.
Like Jonathan said. Best is that you approach every service task assuming it’s going to be long running.
Basically you
Fetch and lock a task for 20 seconds (as that’s the default)
Start your long running task
After 20 seconds you still haven’t completed the task so the engine frees up the lock
Your external task handling service fetches it again and start doing over again on another thread.
You have to either
Fetch and lock it with a very long duration (wrong approach)
Provide an extend lock REST API call to the engine on like 15 seconds basis until your long running task is completed. Since you’re doing Java and as such you’re multithreaded that shouldn’t be a problem.
in gerneral, the REST API does not secured in first place - so no username and password would be required. If you need your Request towards the REST API enhanced in any way, there are 2 options:
Add username and password for Basic Auth with your application.yml like this:
camunda.bpm:
admin-user: # Configure the login credentials for the Runtime Platform admin user
id: demo # configure the username
password: demo # configure the password
client:
base-url: http://localhost:8080/engine-rest # The URL pointing to the Camunda Platform Runtime REST API
async-response-timeout: 1000 # Defines the maximum duration of the long-polling request
worker-id: spring-boot-client # Identifies the worker towards the Engine
# basic-auth: # Configure if REST API is secured with basic authentication
# username: demo
# password: demo
subscriptions:
creditScoreChecker: # This topic name must match the respective `@ExternalTaskSubscription`
process-definition-key: loan_process # Filters for External Tasks of this key
auto-open: false # Defines whether the subscription is opened automatically or not
loanGranter:
lock-duration: 10000 # Defines for how long the External Tasks are locked until they can be fetched again
This example is taken from here.
2. Configure your request rpogrammtically with an Interceptor like this:
@Configuration
public class InterceptorConfiguration {
protected static Logger LOG = LoggerFactory.getLogger(InterceptorConfiguration.class);
@Bean
public ClientRequestInterceptor interceptor() {
return context -> {
LOG.info("Request interceptor called!");
context.addHeader("X-MY-HEADER", "External Tasks Rock!");
};
}
}