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

Revamp retry logic #165

Merged
merged 1 commit into from Jun 17, 2020
Merged

Revamp retry logic #165

merged 1 commit into from Jun 17, 2020

Conversation

ConnorMcMahon
Copy link

The current retry logic had two flaws. First, since it restarted searching from the beginning on each attempt, it could grab the wrong scheduled activity/suborchestration on subsequent events. This could lead to incorrect results. Second, since each retry attempt started from the beginning of the state array, it was not very performant. The new approach only iterates through the state array once per call to callActivityWithRetry() or callSubOrchestrationWithRetry().

@davidmrdavid davidmrdavid self-requested a review April 20, 2020 21:01
let taskScheduled: TaskScheduledEvent | undefined;
let taskFailed: TaskFailedEvent | undefined;
let taskRetryTimer: TimerCreatedEvent | undefined;
for (let i = 0; i < state.length; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we do a foreach / for ... in-style loop here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess in TS its a for...of

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was probably a case of me trying to micro-optimize the perf of this loop. Probably not worth it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaning away from this. I went with the explicit for-loop as we use the index in the loop body.

let subOrchestratorCreated: SubOrchestrationInstanceCreatedEvent | undefined;
let subOrchestratorFailed: SubOrchestrationInstanceFailedEvent | undefined;
let taskRetryTimer: TimerCreatedEvent | undefined;
for (let i = 0; i < state.length; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same nit: for...of preferred

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

const returnValue = name
? state.filter((val: HistoryEvent) => {
return val.EventType === HistoryEventType.TaskScheduled
private findTaskScheduled(state: HistoryEvent[], name: string, startIndex: number = 0): TaskScheduledEvent | undefined {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm mistaken, I don't see startIndex being passed explicitly at any point, so I'm unsure of how to use it

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a holdover from a previous iteration. I got rid of it in the rebase.

Copy link
Collaborator

@davidmrdavid davidmrdavid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me, the changes are reasonable. I have a few nits that I've left as comments.
Something else I would like to see are comments in the callActivityWithRetry and callSubOrchestratorWithRetry, the methods you've modified. Just a few comments on what you're trying to achieve and how would be nice to have.

On another note, don't we call all the findTaskX (scheduled, completed, failed, etc) methods in other places as well? I wonder if we could generalize this optimization into a routine that could be re-used for those places too. In any case, if you agree, we can raise a separate issue for that.

Feel free to merge after reviewing my nits and adding some comments but let's continue our discussion on whether or not this optimization could be generalized / re-used.

The current retry logic had two flaws. First, since it restarted searching from the beginning on each attempt, it could grab the wrong scheduled activity/suborchestration on subsequent events. This could lead to incorrect results. Second, since each retry attempt started from the beginning of the state array, it was not very performant. The new approach only iterates through the state array once per call to callActivityWithRetry() or callSubOrchestrationWithRetry().
Copy link
Collaborator

@davidmrdavid davidmrdavid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead!

@ConnorMcMahon ConnorMcMahon merged commit d789181 into dev Jun 17, 2020
@ConnorMcMahon ConnorMcMahon deleted the CleanupRetryLogic branch June 19, 2020 21:45
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

Successfully merging this pull request may close these issues.

None yet

2 participants