-
Notifications
You must be signed in to change notification settings - Fork 33
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
Initial workflow client #14
Conversation
src/Temporalio/Client/Interceptors/ClientOutboundInterceptor.cs
Outdated
Show resolved
Hide resolved
26f6ee2
to
e5464e0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking pretty good! Nothing blocking
), | ||
Err(err) => match err.downcast::<tonic::Status>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the downcast could be fairly easily avoided by changing the various call methods/macros to return enum errors (use thiserror
or w/e) rather than anyhow errors. They could even be tonic | other
. Makes this match a bit cleaner and the code a bit more maintainable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it does make the match a bit cleaner, that my macros can return any error like inability to decode protos does make that code cleaner (though yes I could have a NotTonic(anyhow::Error)
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The macros should end up with the ability to work the same if you use the auto-From implementations generated by thiserror
public async Task<TResult> GetResultAsync<TResult>( | ||
bool followRuns = true, RpcOptions? rpcOptions = null) | ||
{ | ||
// Continually get pages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little sad that we reimplement pagination in every SDK. This could all be encapsulated in Core if we want (the code is there already), but I suppose we lose out on some low level interception (which I doubt anyone cares much about).
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually I would concur, however I am about to write the history event async iterator which needs to control paging anyways so there'd be no value here. I wrote the interceptor and single-page fetching the way I did here with the expectation of reuse.
/// gRPC status code taken from | ||
/// https://github.com/grpc/grpc-dotnet/blob/master/src/Grpc.Core.Api/StatusCode.cs. | ||
/// </summary> | ||
public enum StatusCode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why copied rather than re-used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to add a dependency on the .NET gRPC library just for this
namespace Temporalio.Exceptions | ||
{ | ||
/// <summary> | ||
/// Thrown when a query is rejected by the worker due to bad workflow status. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth explicitly distinguishing the difference between this and WorkflowQueryFailedException
in the docstring I think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do! Also noticed a typo here that may help explain the difference too
/// Thrown when a query is rejected by the worker due to bad workflow status. | |
/// Thrown when a query is rejected by the server due to bad workflow status. |
// TODO(cretz): Ok to use aggregate exception here or should I just | ||
// comma-delimit into a single message or something? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like that's what it's there for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda, but it's not "AggregateMessageException", it has separate exceptions carrying their own stack traces, causes, etc. But I agree, probably good enough, and bonus is the outputters know how to format this one well.
var afterNow = DateTime.UtcNow.AddSeconds(30); | ||
var temp = desc.CloseTime!.Value; | ||
Assert.InRange(desc.CloseTime!.Value, beforeNow, afterNow); | ||
Assert.InRange(desc.ExecutionTime!.Value, beforeNow, afterNow); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cretz Not sure if you want to add another dependency, but Fluent Assertions library is alot nicer to use and gives better output when assertions fail.
It has a helpers that let you test a date is CloseTo
some time and you pass it a TimeSpan of how close
https://fluentassertions.com/datetimespans/
The object graph comparision also comes in handy
https://fluentassertions.com/objectgraphs/
Also useful is the ability to async retry something and still use assertions in the body (which gives nice errors when it fails)...
Func<Task> asyncRetry = async () =>
{
var describeExecutionResponse = await _stepFunctions.DescribeExecutionAsync(new DescribeExecutionRequest
{
ExecutionArn = executionArn
});
describeExecutionResponse.Should().NotBeNull();
describeExecutionResponse.Status.Should().Be(ExecutionStatus.SUCCEEDED);
};
await asyncRetry.Should().NotThrowAfterAsync(waitTime: 60.Seconds(), pollInterval: 2.Seconds());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the tests grow I very well may add that dependency or other test helpers (I don't mind adding dependencies to our test project). I haven't needed too much yet (and I have started an AssertMore
package at the root of the project for a couple of them).
4db827c
to
15c66ee
Compare
15c66ee
to
0d5869b
Compare
This PR has had as much review as it's going to receive I'm afraid. Merging. |
What was changed
Note, this does not yet include all tests or all features. I am trying to get this in front of people early. I may continue to work on parts for this PR while it remains unapproved.EDIT: This thing is full featured and ready to go.