In Kalix timers, Retry is not stopped after Maxretries

  1. The retry is going indefinitely
    CompletionStage timerRegistration =
    timers().startSingleTimer(
    “DLM API”,
    Duration.ofSeconds(10),
    3,
    Components().schedulerServiceAction().scheduleDLMOrganisationFullSearchRetry(CompanySearchCommands.DLMOrganisationFullSearchRequestRetryCommand.newBuilder().setEntityInstanceId(stateChange.getEntityInstanceId()).build()));

  2. When the Timer duration is over, the call should go to the scheduleDLMOrganisationFullSearchRetry() method, But it is not happening.

Did I miss anything, Please explain

I’m a little confused.

In the title, you seem to mention that it keeps retrying. But in the description, it seems that the call is not being executed at all.

Do you see any exceptions in your logs? Also in the Proxy logs when running locally?

Hi @octonato It is just a piece of code. Actually the timer is running but the timer never stops after maximum retries and also It is not going to the method when the timer expires i.e scheduleDLMOrganisationFullSearchRetry() in the above code snippet.

What could be wrong here? and Do you have any other working example for Timers?

Yes, please check out this sample:

If you can share the full code, I can have a quick look.

Hi Octonato,

We can’t share the code as it resides in a private repo, can’t share for NDA reasons, we also have tried the timers example, the issue might be in our understanding of the functionality.

We have a scenario in which we invoke a kalix action through the timer registration function, the action itself invokes an API outside of the kalix service, we want to retry it say 3 times and if it’s not successful it should expire and invoke another kalix action which basically notifies the user that the above call to the external API failed.

We developed it after referring to the java reliable timers example.
Our understanding is we need to place

  1. the expired method call inside the timerregistration function .
  2. Invoke the actual call to the external api in the thenCompose part of the timerregistration function inside the asyc reply.

if the above understanding is correct then the expired method doesn’t get invoked and the retries don’t stop at say 3 in our case.

Yeah, I think there is a misunderstanding here.

The CompletionStage returned by the Timers API indicates that the timer is registered in Kalix.
It will not have the result of the call you put inside the timer.

The goal of the timer is to execute something later on. So basically, you register a call telling Kalix, please run this in 10 seconds starting from now (as per your example). Kalix takes your request and schedules it to be executed after 10 seconds.

The CompletionStage returned by the API indicates to you that the call was scheduled and that you can proceed with whatever you need to do next.

If I understand your use case, you have a user waiting for the response and you want to try it up to three times before you send a response to the user, correct?

You cannot achieve this with Timers as timers will run asynchronously and detached from the current user request.

To implement this functionality, you should instead have an Action that tries to call the external system 3 times and then recover it in case of failure. There are a few libraries out there that can help with it, like Akka.
It turns out that the Kalix SDK ships with Akka. So the best option for you is to use Akka to achieve this.

Have a look at this piece of documentation:

Make sure you select the Java tab. By default, you will land on the Scala one.