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

add multi instance query support logics #702

Merged
merged 6 commits into from Apr 13, 2022

Conversation

kaibocai
Copy link
Member

@kaibocai kaibocai commented Apr 11, 2022

add multi instance query support logics refer here microsoft/durabletask-java#9 for more details.
This PR includes

  • created general query interface in durable core
  • Implement the query interface in AzureStorageOrchestrationService

@kaibocai kaibocai requested a review from cgillum April 11, 2022 20:59
/// <param name="condition">Return orchestration instances that match the specified conditions.</param>
/// <param name="cancellationToken">Cancellation token that can be used to cancel the status query operation.</param>
/// <returns>Returns each page of orchestration status for all instances and continuation token of next page.</returns>
Task GetOrchestrationStateWithFiltersAsync(OrchestrationStatusQueryCondition condition, CancellationToken cancellationToken);
Copy link
Member Author

@kaibocai kaibocai Apr 11, 2022

Choose a reason for hiding this comment

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

should this method have return type generic as

Task<OrchestrationStatusQueryResult> GetOrchestrationStateWithFiltersAsync(OrchestrationStatusQueryCondition condition, CancellationToken cancellationToken);

to align with what we have in durable extension?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes. Without this, you're not actually returning anything.

Copy link
Collaborator

@cgillum cgillum 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 a good start. I have several suggestions but they are fairly minor.

@@ -0,0 +1,81 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
Copy link
Collaborator

Choose a reason for hiding this comment

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

All the code in this repo is under the Apache license. Please copy/paste the file header that you see for some of the other existing code files.

// Licensed under the MIT License. See LICENSE in the project root for license information.

using System;
using System.Collections.Generic;
Copy link
Collaborator

Choose a reason for hiding this comment

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

The coding convention in this repo is to put the using statements inside the namespace block. See some of the other source files for an example. C# allows you to do either way but I'd like to keep the code as self-consistent as possible.

/// <summary>
/// Determines whether the query will include the input of the orchestration.
/// </summary>
public bool ShowInput { get; set; } = true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's name this FetchInputsAndOutputs.

/// <summary>
/// Return orchestration instances which matches the TaskHubNames.
/// </summary>
public IEnumerable<string> TaskHubNames { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's use ICollection<string> instead of IEnumerable<string>. That will make this API a little easier to use.

/// <summary>
/// Return orchestration instances which matches the runtimeStatus.
/// </summary>
public IEnumerable<OrchestrationStatus> RuntimeStatus { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's use ICollection<OrchestrationStatus> instead if IEnumerable<OrchestrationStatus>. That will make this API a little easier to use.

/// Gets the status of all orchestration instances with paging that match the specified conditions.
/// </summary>
/// <param name="condition">Return orchestration instances that match the specified conditions.</param>
/// <param name="cancellationToken">Cancellation token that can be used to cancel the status query operation.</param>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove the word "status" here.

Suggested change
/// <param name="cancellationToken">Cancellation token that can be used to cancel the status query operation.</param>
/// <param name="cancellationToken">Cancellation token that can be used to cancel the query operation.</param>

/// <param name="condition">Return orchestration instances that match the specified conditions.</param>
/// <param name="cancellationToken">Cancellation token that can be used to cancel the status query operation.</param>
/// <returns>Returns each page of orchestration status for all instances and continuation token of next page.</returns>
Task GetOrchestrationStateWithFiltersAsync(OrchestrationStatusQueryCondition condition, CancellationToken cancellationToken);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes. Without this, you're not actually returning anything.

/// </summary>
public Task GetOrchestrationStateWithFiltersAsync(OrchestrationStatusQueryCondition condition, CancellationToken cancellationToken)
{
var transferredCondition = TransferToAzureStorageCondition(condition);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's not use var here since we can't immediately see the variable type.

Suggested change
var transferredCondition = TransferToAzureStorageCondition(condition);
OrchestrationInstanceStatusQueryCondition convertedCondition = TransferToAzureStorageCondition(condition);

// {
// this.InstanceIdPrefix = "@";
// }
//}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this commented-out code be removed?

/// <summary>
/// Return orchestration instances which were created before this DateTime.
/// </summary>
public DateTime CreatedTimeTo { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

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

It might be a safer API design to make these two properties DateTime? instead of DateTime. That way it's easier to understand whether we want to include them as filter criteria or not. It's very easy to accidentally do the wrong thing when dealing with default values for DateTime.

Copy link
Collaborator

@cgillum cgillum left a comment

Choose a reason for hiding this comment

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

Looks like some code was copied into this project that doesn't need to be. Some more suggestions below, including some class rename suggestions.

/// <summary>
/// Represents the possible runtime execution status values for an orchestration instance.
/// </summary>
public enum OrchestrationRuntimeStatus
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this copied from the Durable Functions extension project? We should not be using this. We should be instead using the existing DurableTask.Core.OrchestrationStatus enum mentioned in the comment on line 17 since that already exists in this assembly. No need to create yet another copy of it.

// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like you double-copied the license text?

/// <summary>
/// Represents the status of a durable orchestration instance.
/// </summary>
public class DurableOrchestrationStatus
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this also copied from the Durable Functions extension project? You should instead be using the existing DurableTask.Core.OrchestrationState class.

}

internal OrchestrationInstanceStatusQueryCondition TransferToAzureStorageCondition(OrchestrationStatusQueryCondition condition)
private OrchestrationInstanceStatusQueryCondition ToAzureStorageCondition(OrchestrationStatusQueryCondition condition)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's make this method static since it doesn't reference this anywhere.

Suggested change
private OrchestrationInstanceStatusQueryCondition ToAzureStorageCondition(OrchestrationStatusQueryCondition condition)
private static OrchestrationInstanceStatusQueryCondition ToAzureStorageCondition(OrchestrationStatusQueryCondition condition)

Doing so actually creates a slight performance improvement but more importantly helps the reader better understand the scope of the method.

/// <summary>
/// Return orchestration instances which matches the runtimeStatus.
/// </summary>
public IEnumerable<OrchestrationStatus> RuntimeStatus { get; set; }
public ICollection<OrchestrationRuntimeStatus>? RuntimeStatus { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should be using OrchestrationStatus here.

Suggested change
public ICollection<OrchestrationRuntimeStatus>? RuntimeStatus { get; set; }
public ICollection<OrchestrationStatus>? RuntimeStatus { get; set; }

public async Task<OrchestrationStatusQueryResult> GetOrchestrationStateWithFiltersAsync(OrchestrationStatusQueryCondition condition, CancellationToken cancellationToken)
{
OrchestrationInstanceStatusQueryCondition convertedCondition = this.ToAzureStorageCondition(condition);
var statusContext = await this.GetOrchestrationStateAsync(convertedCondition, condition.PageSize, condition.ContinuationToken, cancellationToken);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's avoid using var unless the type is already mentioned in the right-hand expression (which it's not in this case).

Suggested change
var statusContext = await this.GetOrchestrationStateAsync(convertedCondition, condition.PageSize, condition.ContinuationToken, cancellationToken);
IList<OrchestrationState> statusContext = await this.GetOrchestrationStateAsync(convertedCondition, condition.PageSize, condition.ContinuationToken, cancellationToken);

/// <summary>
/// Query condition for searching the status of orchestration instances.
/// </summary>
public class OrchestrationStatusQueryCondition
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's rename this to OrchestrationQuery. It's more similar to other Microsoft query APIs, like Azure Storage table query APIs.

Copy link
Collaborator

@cgillum cgillum left a comment

Choose a reason for hiding this comment

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

Very close, just a few more small things.

src/DurableTask.Core/Query/OrchestrationQuery.cs Outdated Show resolved Hide resolved
src/DurableTask.Core/Query/OrchestrationQueryResult.cs Outdated Show resolved Hide resolved
src/DurableTask.Core/Query/OrchestrationQueryResult.cs Outdated Show resolved Hide resolved
Copy link
Collaborator

@cgillum cgillum left a comment

Choose a reason for hiding this comment

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

A few more small details...

src/DurableTask.Core/Query/OrchestrationQueryResult.cs Outdated Show resolved Hide resolved
src/DurableTask.Core/Query/OrchestrationQueryResult.cs Outdated Show resolved Hide resolved
src/DurableTask.Core/Query/OrchestrationQueryResult.cs Outdated Show resolved Hide resolved
Copy link
Collaborator

@cgillum cgillum left a comment

Choose a reason for hiding this comment

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

Looks great!

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