Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize timer started for saving cost #465

Open
longquanzheng opened this issue Oct 24, 2024 · 0 comments
Open

Optimize timer started for saving cost #465

longquanzheng opened this issue Oct 24, 2024 · 0 comments

Comments

@longquanzheng
Copy link
Contributor

longquanzheng commented Oct 24, 2024

It's a common pattern using iwf workflow like this:

class UpdatableTimerState implements WorkflowState<Void> {

    @Override
    public CommandRequest waitUntil(Context context, ...) {
        return CommandRequest.forAnyCommandCompleted(
                TimerCommand.createByDuration(TIMEOUT_DURATION)),
                InternalChannelCommand.create(CHANNEL_RESET_TIMER)
        );
    }

    @Override
    public StateDecision execute(Context context, Void input, CommandResults commandResults,...) {
        TimerCommandResult timer = commandResults.getTimerResult(0);
        if (timer.getStatus() == FIRED) {
              // timer fires, call API to send an email
              svc.sendEmail(...);
              // assuming we want to complete workflow here
              return StateDecision.completeWorkflow();
        }
        // otherwise the channel receives a message to reset the timer
        return StateDecision.singleNextState(UpdatableTimerState.class);
    }

When doing this, a new timer would always created when receiving a REST TIMER message.
We could potentially lazily create it when needed. For example --
if the first timer is 30 days, and after one day, it tries to create another 30 day timer, after another day, it will create another 30 day timer again, so there are 3 timers created in history.

Instead, we could keep the first timer, and only create a new timer when the first timer is fired, and check if there is another timer needed.

Note that this optimization is now possible to implement relatively easy because iwf has a dedicated component to manage all the timers -- TimerProcessor:

  • It contains all the real timers in member fields stateExecutionCurrentTimerInfos
    • continueAsNew is implemented already for it.
  • The temporal timers are actually started in a centralized place in WaitForTimerFiredOrSkipped method.

So technically this optimization can be done within this component, without changing anything else.

It would be safer to enable by config, then later on when it's stable, use versioning to enable for all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant