Skip to content

Conversation

@mfateev
Copy link
Member

@mfateev mfateev commented Jul 31, 2020

  • Updated DataConverter API to support extracting individual values from the serialized list.
  • Renamed EncodedValue to EncodedValues.
  • Added ApplicationFailure factories for clarity.

@mfateev mfateev requested a review from mastermanu July 31, 2020 01:37
Type[] genericParameterTypes)
throws DataConverterException {
if (parameterTypes != null
&& (parameterTypes == null || parameterTypes.length != genericParameterTypes.length)) {
Copy link
Member

Choose a reason for hiding this comment

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

the first clause of this condition checks that parameterTypes is not null, so this parameterTypes==null check is unnecessary, right? Or did you mean to check if genericParameterTypes is null?

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch!

for (int i = 0; i < parameterTypes.length; i++) {
Class<?> pt = parameterTypes[i];
Type gt = genericParameterTypes[i];
if (i >= count) {
Copy link
Member

Choose a reason for hiding this comment

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

what if the count of payloads is much greater than that of the parameters? Basically does the user need to know that they are missing out on some payloads? Or is this well understood?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question. The current answer is that it is needed to be able to add and remove arguments of functions.

} else {
if (converter == null) {
throw new IllegalStateException("converter not set");
if (payloads.isPresent()) {
Copy link
Member

Choose a reason for hiding this comment

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

we are guaranteed that at least one of values / payloads is not null right? Basically, values and payloads cannot both be null because (Object... values) guarantees values is at least of length 0 if that constructor is used?

Copy link
Member Author

Choose a reason for hiding this comment

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

In a lot of cases, Payloads are not set at all if there are no any values. But we probably need to audit for this.

if (converter == null) {
throw new IllegalStateException("converter not set");
}
return converter.fromPayloads(index, payloads, parameterType, genericParameterType);
Copy link
Member

Choose a reason for hiding this comment

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

No need to initialize / cache the converted object into the values array right?

Copy link
Member Author

Choose a reason for hiding this comment

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

The idea of Values is that it can be created with objects or Payloads. I'm not sure if caching is really going to help here as every value accessed only once I believe.

private boolean nonRetryable;

/**
* New ApplicationFailure with {@link #isNonRetryable()} flag set to false. Note that this
Copy link
Member

@mastermanu mastermanu Jul 31, 2020

Choose a reason for hiding this comment

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

didn't quite follow the 2nd sentence of this comment. did you mean to say if the type is NOT included

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch.

*/
public ApplicationFailure(String message, String type, Object details, Exception cause) {
this(message, type, new EncodedValue(details), false, cause);
public static ApplicationFailure newFailure(String message, String type, Object... details) {
Copy link
Member

Choose a reason for hiding this comment

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

why not just call it newRetryableFailure?

Copy link
Member Author

Choose a reason for hiding this comment

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

I called it initially. But then I found that it is very confusing that it can be not retried if the policy says so.

public ApplicationFailure(String message) {
this(message, null);
static ApplicationFailure newFromValues(
String message, String type, boolean nonRetryable, Values details, Throwable cause) {
Copy link
Member

Choose a reason for hiding this comment

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

[Nit], having boolean names that are negative (nonRetryable vs retryable) can be kind of confusing

Copy link
Member Author

Choose a reason for hiding this comment

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

I almost always follow the pattern that the default value should be the default value for the type. So the default of the boolean type is false. So the field is called nonRetryable as its default is false. But I agree that it looks weird in the parameter name.

}
Optional<Payloads> details = info.getHeartbeatDetails();
return Optional.ofNullable(dataConverter.fromPayloads(details, detailsClass, detailsType));
return Optional.ofNullable(dataConverter.fromPayloads(0, details, detailsClass, detailsType));
Copy link
Member

@mastermanu mastermanu Jul 31, 2020

Choose a reason for hiding this comment

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

we didn't want this function to have an overload without the index that internally assumes the first element? seems painful to pass in 0 every time

Copy link
Member Author

Choose a reason for hiding this comment

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

This class is used only internally by the SDK, so I think having an explicit index makes sense to indicate that it can hold multiple values.

assertEquals("foo", ((ApplicationFailure) e.getCause()).getType());
assertEquals("details", ((ApplicationFailure) e.getCause()).getDetails().get(String.class));
assertEquals(
"details1", ((ApplicationFailure) e.getCause()).getDetails().get(0, String.class));
Copy link
Member

Choose a reason for hiding this comment

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

and we still have a test that validates get without the index specified works fine?

Copy link
Member Author

Choose a reason for hiding this comment

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

I checked and found at least two unit tests that call it.

return converter.fromPayloads(payloads, parameterType, genericParameterType);
if (values != null) {
@SuppressWarnings("unchecked")
T result = (T) values[index];
Copy link
Member

Choose a reason for hiding this comment

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

if the user exceeds the bounds of the values/payload, no issues right?

@mfateev mfateev merged commit 19c701d into temporalio:master Jul 31, 2020
@mfateev mfateev deleted the details branch July 31, 2020 02:49
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.

2 participants