How to keep subscribing to the topic without actually specifying the lockDuration

Hey there,
I have a service task which is basically an External Task, meaning it publishes to the topic specified in the field, and the class where I am subscribing to the topic, susbscribes to the task based on the topic name, now if at all in-case, i have to keep listening to the topic forever, i mean the lock should be forever, and should not expire.
Actual outcome, though i am not mentioning the lockDuration on the topic subscribed, the topic automatically gets unsubscribed after a period of time.
Expected Outcome: The Topic should be subscribed by this workerId.

Here is the piece of code, that I have written, using https://github.com/camunda/camunda-external-task-client-java/tree/master/examples/loan-granting, Suggested @Niall :

    ExternalTaskClient client = ExternalTaskClient.create()
                    .baseUrl(PROCESS_ENGINE_URL)
                    .build();
 client.subscribe("generateNotification")
                .handler((externalTask, externalTaskService) -> {
//i am doing my stuff here, getting and setting variables
externalTaskService.complete(externalTask);
}).open()

Thanks Much.

the topic automatically gets unsubscribed after a period of time

What gives you this impression? Based on just this snippet, the external task client should continue to poll the Camunda REST API for tasks on the generateNotification topic, until you explicitly tell it to stop or you close the subscription. It’s not until the client fetches the tasks that the lock duration comes into play. The tasks being fetched are locked in the external task table (according to the lock duration you set, 20s default with the Java client if you don’t) so that another worker can’t come along and fetch those same tasks until the expiration of the lock duration.

Hi @jgigliotti, you were right, the client was listening to the topic forever, however when i am using the above code, there is some latency, I mean, even though the execution has reached the external task, the System.out.println in the above are getting displayed after some time. I fixed that issue, using below code, but i want to understand why is that happening.

  ExternalTaskClient client = ExternalTaskClient.create()
            .baseUrl(PROCESS_ENGINE_URL)
            .disableBackoffStrategy().workerId("eventWorker")
            .build();
 TopicSubscriptionBuilder generateNotificationTopicSubscriptionBuilder= client.subscribe("generateNotification")
                .handler((externalTask, externalTaskService) -> {
//i am doing my stuff here, getting and setting variables
externalTaskService.complete(externalTask);
});
client.start();
generateNotificationTopicSubscriptionBuilder.open();

Thanks

I think your answer is in the default backoff strategy. It looks as though, be default, there is an exponential backoff that accrues while there are no external tasks. If you’re just getting everything setup and your external tasks have been empty for a bit, it could take up to 60 seconds to process the first external task. You can do some experimenting to verify, but I think once you start receiving many external tasks, there should be very little latency while processing a reasonable number of external tasks, all the way up to the point where your worker(s) get overwhelmed.

Hi @jgigliotti,

Thanks for the response, I will verify that.
Thanks much @jgigliotti

Hi @jgigliotti
I have a doubt, Inside a camunda workflow, I have a service task, where I can tell my task to be external task and give a topic. Now my question is Can I create a topic inside my service task of type Java Class. I mean there is no Service Task of type External task physically inside camunda workflow, I want to create a topic inside my Service class of type Java Implementation.

Can I ask, why are trying to that from a java service task? I can’t say I’ve seen that before. Is there some functionality that the External Task doesn’t provide that you need?

Hi @jgigliotti,
Sorry i was travelling and couldn’t reply on time. Yeah, so i shouldnt be doing that from a service task, you are right. I am using an external task now, but I have a problem here while updating variables. I am having an Object which has String as and Object as value. Now when i am trying to modify properties of this object and trying to set it as process variable. I am facing some issue.

ProcessVariable: mapOfEvents
Value: {“Tailings-Failure_Prediction”:{“isHysteresis”:false,“setCondition”:false,“time”:“2020-05-27T11:30:05.204+05:30”}}

In my external task i am getting this process variable and i am trying to add additional field: after modification this is what it is:
{“Tailings-Failure_Prediction”:{“isHysteresis”:false,“setCondition”:false,“time”:“2020-05-27T11:30:05.204+05:30”, “role”:“key”}}

Consider this is the format:

   JSONObject allStoredEvents =new JSONObject();
    allStoredEvents.put("lol", "lol");
    JSONObject newData= new JSONObject();
    newData.put("kyu", allStoredEvents);

Now when i am trying to update the process Variable, using externalService.complete(external, Collections.singletonMap(“mapOfEvents”, allStoredEvents));

When i am doing this, and when i check for the processvariable inside the cockpit, the format of the process variable has been changed from org.json.simple.JSONObject to
org.json.simple.JSONObject<java.lang.Object,java.lang.Object>.

When i click on the deserialize tab in cockpit, I am getting following error:
Deserialization Error: Cannot deserialize object in variable 'mapOfEvents': SPIN/JACKSON-JSON-01007 Cannot construct java type from string 'org.json.simple.JSONObject<java.lang.Object,java.lang.Object>'

It’s tough to say without knowing more about your project/deployment. It looks like you’re using org.json.simple.JSONObject in your external service. You would need to make sure that dependency is deployed with the engine in order for it to deserialize it properly. If you’re just trying to get an example working, I would start by persisting the process variables like the example you referenced in your first post.