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

feat: data error response update #176

Merged
merged 8 commits into from
Sep 26, 2022
Merged

Conversation

pgautier404
Copy link
Contributor

No description provided.

@@ -1,8 +1,27 @@
namespace Momento.Sdk.Responses;

using Momento.Sdk.Exceptions;

public class CacheDeleteResponse
Copy link
Contributor

Choose a reason for hiding this comment

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

can't remember if we decided we were going to make these abstract, nbd though

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 did, and I did for the control responses but not the data ones. Fixed in efab849.

public IEnumerable<string?> Strings()
{
return Responses.Select(response => response.String());
public IEnumerable<CacheGetStatus> Status
Copy link
Contributor

Choose a reason for hiding this comment

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

@malandis you should look at this part. i'm not super familiar with this part of the API but some random thoughts I have are:

  1. We have been getting rid of the enums in other places, and I had assumed that would happen for CacheGet too, but it seems like it's not happening here.
  2. do we really need 3 separate methods for this? would it not be okay to just have a single enumerable that contains the polymorphic parent type?
  3. in the loops below it looks like we are assuming that all of the responses are Success, but I don't think there is any guarantee that that is actually true?

Copy link
Contributor

Choose a reason for hiding this comment

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

  1. You could. I included methods to parallel the unary Get: get the status, get the payload. Since this is a batch operation I also included to get the individual items
  2. That's correct for the way this is implemented now. If this were a single RPC then there would only be on Success

public class Success : CacheGetResponse
{
public CacheGetStatus Status { get; }
protected readonly ByteString? value;
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 have expected us to have sub classes for Hit and Miss here, and thus avoid the nullable stuff like we were doing elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're totally right . . . I was just in a rhythm :-) Fixed in 0aa3060.

Copy link
Contributor

Choose a reason for hiding this comment

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

That commit looks a great improvement but the field is still nullable here... it shouldn't need to be anymore, should it?

public IEnumerable<string?> Strings()
{
return Responses.Select(response => response.String());
public IEnumerable<CacheGetStatus> Status
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. You could. I included methods to parallel the unary Get: get the status, get the payload. Since this is a batch operation I also included to get the individual items
  2. That's correct for the way this is implemented now. If this were a single RPC then there would only be on Success

Comment on lines 41 to 45
byte[]? setValue = (await client.GetAsync(cacheName, key)).ByteArray;
Assert.Equal(value, setValue);
CacheGetResponse response = await client.GetAsync(cacheName, key);
if (response is CacheGetResponse.Success goodResponse) {
byte[]? setValue = goodResponse.ByteArray;
Assert.Equal(value, setValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The previous tests assumed a Success. Otherwise they would throw an exception and the test would fail. In this version if the response is not a success, the test still passes. So we need an explicit check to assert Success

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed that I was potentially causing false positives in those spots too, thanks. I've updated these to use a direct cast outside of an if, so the tests will fail if the subtype we're expecting isn't the one we get. This should address the remainder of your comments as well.

Comment on lines 47 to 54
setValue = (await client.GetAsync(cacheName, key)).ByteArray;
Assert.Equal(value, setValue);
response = await client.GetAsync(cacheName, key);
if (response is CacheGetResponse.Success anotherGoodResponse) {
byte[]? setValue = anotherGoodResponse.ByteArray;
Assert.Equal(value, setValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Comment on lines 76 to 86
string? setValue = (await client.GetAsync(cacheName, key)).String();
Assert.Equal(value, setValue);
CacheGetResponse response = await client.GetAsync(cacheName, key);
if (response is CacheGetResponse.Success goodResponse) {
string? setValue = goodResponse.String();
Assert.Equal(value, setValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Comment on lines 82 to 95
setValue = (await client.GetAsync(cacheName, key)).String();
Assert.Equal(value, setValue);
response = await client.GetAsync(cacheName, key);
if (response is CacheGetResponse.Success anotherGoodResponse) {
string? setValue = anotherGoodResponse.String();
Assert.Equal(value, setValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Comment on lines 111 to 127
byte[]? setValue = (await client.GetAsync(cacheName, key)).ByteArray;
Assert.Equal(value, setValue);
CacheGetResponse response = await client.GetAsync(cacheName, key);
if (response is CacheGetResponse.Success goodResponse) {
byte[]? setValue = goodResponse.ByteArray;
Assert.Equal(value, setValue);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Comment on lines 117 to 135
setValue = (await client.GetAsync(cacheName, key)).ByteArray;
Assert.Equal(value, setValue);
response = await client.GetAsync(cacheName, key);
var anotherGoodResponse = (CacheGetResponse.Success)response;
byte[]? anotherSetValue = anotherGoodResponse.ByteArray;
Assert.Equal(value, anotherSetValue);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Comment on lines 183 to 205
await Assert.ThrowsAsync<Momento.Sdk.Exceptions.TimeoutException>(async () => await simpleCacheClient.GetBatchAsync(cacheName, keys));
CacheGetBatchResponse response = await simpleCacheClient.GetBatchAsync(cacheName, keys);
if (response is CacheGetBatchResponse.Error badResponse) {
Assert.Equal(MomentoErrorCode.TIMEOUT_ERROR, badResponse.ErrorCode);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same test comment

Copy link
Contributor

@cprice404 cprice404 left a comment

Choose a reason for hiding this comment

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

This looks really close to being done IMO, but I'd like to hear you thoughts on whether the bytearray in the Hit class still needs to be nullable.

{
var ret = new List<CacheGetStatus>();
foreach (CacheGetResponse response in Responses) {
if (response is CacheGetResponse.Hit hitResponse) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These look better/safer now, so thanks for changing them.

I'm still feeling iffy about this part of the API as a whole, so I think we should revisit it and have a convo about it later this week, but I think it's okay for now for this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, the batch stuff needs some love and we should take a closer look when time allows.

public class Success : CacheGetResponse
{
public CacheGetStatus Status { get; }
protected readonly ByteString? value;
Copy link
Contributor

Choose a reason for hiding this comment

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

That commit looks a great improvement but the field is still nullable here... it shouldn't need to be anymore, should it?


// _GetResponse serverResponseBadRequest = new _GetResponse() { Result = ECacheResult.Invalid };
// _ = Assert.Throws<InternalServerException>(() => new CacheGetResponse.Success(serverResponseBadRequest));
Copy link
Contributor

Choose a reason for hiding this comment

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

intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, those are obsolete due to class restructuring. The response subtypes are tested in the integration tests, so we're not losing coverage.

@pgautier404
Copy link
Contributor Author

Great callout on value no longer needing to be nullable. Fixed in 5b620a0.

Copy link
Contributor

@cprice404 cprice404 left a comment

Choose a reason for hiding this comment

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

cool, thanks. I think we should merge this as-is because it's a good step forward, but would like to circle back quickly and see if the enum is still necessary at all. It feels like the only thing that is currently forcing us to keep it is that batch api, and if that's true, we should talk about options for getting rid of that bit, because having the enum here feels inconsistent since we got rid of it in the other places.

public class Hit : CacheGetResponse
{
public CacheGetStatus Status { get => CacheGetStatus.HIT; }
protected readonly ByteString value;
Copy link
Contributor

Choose a reason for hiding this comment

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

cool, thanks. I think we should merge this as-is because it's a good step forward, but would like to circle back quickly and see if the enum is still necessary at all. It feels like the only thing that is currently forcing us to keep it is that batch api, and if that's true, we should talk about options for getting rid of that bit, because having the enum here feels inconsistent since we got rid of it in the other places.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds good. The enum shouldn't be necessary but removing it altogether as part of this effort seemed risky.

@pgautier404 pgautier404 merged commit ca93db7 into main Sep 26, 2022
@pgautier404 pgautier404 deleted the feat/data-error-response-update branch September 26, 2022 18:26
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.

3 participants