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

Reuse ExecutionStrategy instance #21350

Closed
AndriySvyryd opened this issue Jun 20, 2020 · 7 comments · Fixed by #25836
Closed

Reuse ExecutionStrategy instance #21350

AndriySvyryd opened this issue Jun 20, 2020 · 7 comments · Fixed by #25836
Labels
area-dbcontext area-perf closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@AndriySvyryd
Copy link
Member

It can be stored in the DbContext

@martincostello
Copy link
Member

I'd be happy to try and pick this up if you could provide a little more detail about the intended design for storing a strategy in the DbContext.

@AndriySvyryd
Copy link
Member Author

Add a field to DbContext
When a new strategy instance is requested and the field is not null then reset its state, return it and set the field to null.
When a strategy instance finishes execution and the field on DbContext is null then store it there.

To encapsulate the field add an interface with a property in .Internal namespace that is implemented explicitly by the DbContext.

@AndriySvyryd
Copy link
Member Author

Alternatively, you can store it in the IExecutionStrategyFactory implementation, add a Return(IExecutionStrategy) to IExecutionStrategyFactory and add IExecutionStrategyFactory to ExecutionStrategyDependencies (setting it in the ExecutionStrategyFactory constructor).

@AndriySvyryd
Copy link
Member Author

The latter approach has better separation of concerns and avoids having to add yet another interface.

@martincostello
Copy link
Member

Looking at the code, I don't quite follow the second suggestion. ExecutionStrategyDependencies is used to create an execution strategy, so wouldn't contain an instance of the object itself? Also there appear to be 4 different strategy implementations that would all be updating to be "re-use aware", where as the first option would make re-use an implementation detail in just the one place?

Maybe the new field could be added to DatabaseFacade instead and it cached there?

public virtual IExecutionStrategy CreateExecutionStrategy()
=> Dependencies.ExecutionStrategyFactory.Create();

@martincostello
Copy link
Member

Ah, but then Create() is called from other places than DatabaseFacade like StateManager, CosmosClientWrapper etc.

It's not obvious to me what the best place to funnel all the calls through to maximise re-use would be.

@AndriySvyryd
Copy link
Member Author

ExecutionStrategyDependencies is used to create an execution strategy, so wouldn't contain an instance of the object itself?

Yes, that's why it needs to be set from the IExecutionStrategyFactory implementation constructor.

Also there appear to be 4 different strategy implementations that would all be updating to be "re-use aware", where as the first option would make re-use an implementation detail in just the one place?

Separate implementations is not a downside. For example, NonRetryingExecutionStrategy doesn't contain any state, so ExecutionStrategyFactory could just always return a singleton instance.

@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Sep 2, 2021
@AndriySvyryd AndriySvyryd removed their assignment Sep 2, 2021
AndriySvyryd added a commit that referenced this issue Sep 2, 2021
Don't pass null to ExecutionStrategy.ShouldRetryOn.
Use the currently executing execution strategy to determine whether buffering is needed.

Fixes #21350
Fixes #23019
Fixes #21463
AndriySvyryd added a commit that referenced this issue Sep 2, 2021
Don't pass null to ExecutionStrategy.ShouldRetryOn.
Use the currently executing execution strategy to determine whether buffering is needed.

Fixes #21350
Fixes #23019
Fixes #21463
AndriySvyryd added a commit that referenced this issue Sep 2, 2021
Don't pass null to ExecutionStrategy.ShouldRetryOn.
Use the currently executing execution strategy to determine whether buffering is needed.

Fixes #21350
Fixes #23019
Fixes #21463
AndriySvyryd added a commit that referenced this issue Sep 3, 2021
Don't pass null to ExecutionStrategy.ShouldRetryOn.
Use the currently executing strategy to determine whether buffering is needed.

Fixes #21350
Fixes #23019
Fixes #21463
@ajcvickers ajcvickers modified the milestones: 6.0.0, 6.0.0-rc2 Sep 4, 2021
@ajcvickers ajcvickers modified the milestones: 6.0.0-rc2, 6.0.0 Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dbcontext area-perf closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants