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

[Storage][Core] Wait for environment to become eventually consistent. #20574

Conversation

kasobol-msft
Copy link
Contributor

@kasobol-msft kasobol-msft commented Apr 21, 2021

This is another attempt to solve #17384 and Azure/azure-sdk-tools#1567 .

Based on discussion in #20559 .

The idea is that:

  • TestEnvironment exposes a overridable method that represents service provided sampling scenario
  • RecordedTestBase<TEnvironment> shall keep executing the sampling scenario until it signals it's ready (or fail fast if the error is severe)
  • Service will implement sampling scenario to call some API that fail if environment hasn't reach usable state

Out of scope:

  • Moving configuration from StorageTestBase to StorageTestEnvironment. However some work towards it is accomplished here.
  • The retry strategy and it's configuration in RecordedTestBase<TEnvironment> is simplified now. I think we should make it fancy when there's a need.
  • I'll cover other storage services in separate PR. Here just blobs as PoC.

@ghost ghost added Azure.Core Storage Storage Service (Queues, Blobs, Files) labels Apr 21, 2021
@kasobol-msft kasobol-msft marked this pull request as ready for review April 21, 2021 19:02
@kasobol-msft
Copy link
Contributor Author

/azp run net - storage - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

/// Throw if you want to fail the run fast.
/// </summary>
/// <returns>Whether environment is ready to use.</returns>
public virtual Task<bool> IsEnvironmentReady()
Copy link
Contributor

Choose a reason for hiding this comment

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

protected

/// </summary>
/// <returns>A task.</returns>
public async Task WaitForEnvironment()
{
Copy link
Contributor

Choose a reason for hiding this comment

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

We might have a problem if multiple classes call this method in parallel. Consider having an IDictionary<Type, Task> where we initialize the task immediately and then await on it.

Copy link
Contributor

Choose a reason for hiding this comment

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

It would also have a nice side-effect of caching the exception.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup and it got rid of the enum.

Copy link
Member

@JoshLove-msft JoshLove-msft Apr 21, 2021

Choose a reason for hiding this comment

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

Why do we need per-class invocations of WaitForEnvironmentInternal? The logic can't vary per test class, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We call into virtual method where service team provides sampling scenario. I don't think we can do this from static context.

Copy link
Member

Choose a reason for hiding this comment

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

Nevermind, this is per Environment type.

@kasobol-msft
Copy link
Contributor Author

/azp run net - storage - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@@ -23,5 +27,11 @@ public override void StartTestRecording()
}

public TEnvironment TestEnvironment { get; }

[OneTimeSetUp]
public async Task WaitForEnvironment()
Copy link
Member

Choose a reason for hiding this comment

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

Should we make this ValueTask since it will usually complete synchronously?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If somebody decides they need "sampling" they'll most likely end up calling API like this:
https://github.com/kasobol-msft/azure-sdk-for-net/blob/dd244f41ee9c999dc09cb42cbd72930f1320770d/sdk/storage/Azure.Storage.Blobs/tests/BlobTestEnvironment.cs#L12-L30
So, this task here would chain to async api call worst case.
Could you elaborate more how would you use ValueTask in this logic?

Copy link
Member

@JoshLove-msft JoshLove-msft Apr 21, 2021

Choose a reason for hiding this comment

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

Well, if the method isn't overriden then it would complete synchronously. But I suppose since we are returning Task<bool> the runtime is able to use cached instances for these so it probably doesn't provide much benefit. Also, we'd have to call AsTask anyway when putting them into the dictionary, so I think using Task makes sense.

https://devblogs.microsoft.com/dotnet/understanding-the-whys-whats-and-whens-of-valuetask/#task

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good read. How does it look now?
One place I had to retain task is the cache as we shouldn't be await on ValueTasks multiple times (per that article).

Copy link
Member

Choose a reason for hiding this comment

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

Yep, that is what I was thinking when I mentioned needing to call AsTask, but I think how you have it is even better.

Copy link
Member

Choose a reason for hiding this comment

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

Being that we still have to allocate a task, I don't think there is any practical difference between using ValueTask<T> and Task<T> here, but ValueTask still seems to convey the intent of the API better. /cc @pakrym to keep me honest here

Copy link
Contributor

Choose a reason for hiding this comment

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

I would say task vs valuetask doesn't matter in this situation at all. We have so many way larger inefficiencies in the test framework.

But ValueTask<T> and Task<T> difference matters for sync completion mostly. ValueTask<T> won't allocate when completed synchronously. But Task<bool> return value are cached(by the runtime) so it won't allocate as well

/// Waits until environment becomes ready to use. See <see cref="IsEnvironmentReady"/> to define sampling scenario.
/// </summary>
/// <returns>A task.</returns>
public async Task WaitForEnvironment()
Copy link
Member

Choose a reason for hiding this comment

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

Consider suffixing with Async.

/// Throw if you want to fail the run fast.
/// </summary>
/// <returns>Whether environment is ready to use.</returns>
protected virtual Task<bool> IsEnvironmentReady()
Copy link
Member

Choose a reason for hiding this comment

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

Consider suffixing with Async.

@JoshLove-msft
Copy link
Member

This is really cool. Would you like to add a blurb to the Readme - https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/core/Azure.Core.TestFramework/README.md

Copy link
Contributor

@pakrym pakrym left a comment

Choose a reason for hiding this comment

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

This is great! Thank you for taking time to do this.

@kasobol-msft
Copy link
Contributor Author

/azp run net - storage - tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@kasobol-msft kasobol-msft merged commit 2aa289c into Azure:master Apr 21, 2021
@kasobol-msft kasobol-msft deleted the deal-with-rbac-replication-lag-attempt-2 branch April 21, 2021 22:30
azure-sdk pushed a commit to azure-sdk/azure-sdk-for-net that referenced this pull request Sep 11, 2022
Adding archive/unarchive to Microsoft.Capacity 2022-03-01 (Azure#20574)

* Adding archive/unarchive to Microsoft.Capacity 2022-03-01

* fix

* format
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Azure.Core Storage Storage Service (Queues, Blobs, Files)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants