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

chore: add fieldValueDictionary accessor to dictionaryGetBatch #65

Merged
merged 16 commits into from
Nov 17, 2022

Conversation

poppoerika
Copy link
Contributor

Added fieldValueDictionary accessor to dictionaryGetBatch to return an array of field/value pairs.
Also, updated dictionary accessor to fieldValueDictionary for dictionaryFetch to be consistent with naming.
Corresponding tests are also updated.

Closes #53

@@ -1020,6 +1024,11 @@ public function valuesArray(): array
return $ret;
}

public function fieldValueDictionary(): array
Copy link
Contributor

Choose a reason for hiding this comment

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

I think by our naming conventions this would start with value. I think maybe it would be valueDictionary but let's get @pgautier404 to weigh in.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, everything should begin with value. I thought we were going to go with something like valueArray() because dictionaries are arrays in PHP, but I could go with either name as long as it's consistent.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor

@cprice404 cprice404 Nov 15, 2022

Choose a reason for hiding this comment

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

@@ -1020,6 +1024,11 @@ public function valuesArray(): array
return $ret;
Copy link
Contributor

Choose a reason for hiding this comment

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

also i think we might want to change the name of valuesArray to just responses? Since it's not actually returning values directly, but rather, an array of objects that may have values in them?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@cprice404 this actually is extracting the values from the responses and returning them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@@ -576,7 +576,7 @@ public function dictionaryGetBatch(string $cacheName, string $dictionaryName, ar
return new CacheDictionaryGetBatchResponseError(new UnknownError($e->getMessage()));
}
if ($dictionaryGetBatchResponse->hasFound()) {
return new CacheDictionaryGetBatchResponseSuccess($dictionaryGetBatchResponse);
return new CacheDictionaryGetBatchResponseSuccess($dictionaryGetBatchResponse, fields: $fields);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you have another PR up that may have conflicts with this one, yes? Where this class gets renamed to *DictionaryGetFields*? Just calling it out to make sure that we end up with the correct one before the final merge.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah this is the PR for that: #64

@poppoerika
Copy link
Contributor Author

@pgautier404 @cprice404
We want to return two values from dictionaryGetFields (which is dictionaryGetBatch in this branch still)

  1. an array containing CacheDictionaryGetResponse's values; in case of HIT, it's a string value, and in vase of MISS, it's null (currently this is called valuesArray)
  2. an array containing field/value pairs, which I named fieldValueDictionary.

For 1, I think we can keep the name as is. Or we can rename this to responses to align with our .NET SDK, although it doesn't follow the value<type> naming convention.
For 2, I wanted to hear your opinion. I chose fieldValueDictionary because I wanted to differentiate it from valuesArray since it contains field/value pairs compared to just values. How about fieldStringValueStringArray to represent a content inside?
This suggestion will be changed depending on our decision for 1.

@pgautier404
Copy link
Collaborator

@pgautier404 @cprice404 We want to return two values from dictionaryGetFields (which is dictionaryGetBatch in this branch still)

1. an array containing `CacheDictionaryGetResponse`'s values; in case of HIT, it's a string value, and in vase of MISS, it's `null` (currently this is called `valuesArray`)

2. an array containing field/value pairs, which I named `fieldValueDictionary`.

For 1, I think we can keep the name as is. Or we can rename this to responses to align with our .NET SDK, although it doesn't follow the value<type> naming convention. For 2, I wanted to hear your opinion. I chose fieldValueDictionary because I wanted to differentiate it from valuesArray since it contains field/value pairs compared to just values. How about fieldStringValueStringArray to represent a content inside? This suggestion will be changed depending on our decision for 1.

The .NET SDK is returning responses without extracting values from them in a Responses property. There are also methods for returning the extracted values of responses as a list of strings or a list of byte arrays. It doesn't return key/value pairs anywhere. We need to do the same. Like Chris suggested, the function returning the list of responses should just be called responses, and the list of extracted values should be called valuesString().

@cprice404 @malandis can you sanity check me here please?

@cprice404
Copy link
Contributor

@pgautier404 @cprice404 We want to return two values from dictionaryGetFields (which is dictionaryGetBatch in this branch still)

1. an array containing `CacheDictionaryGetResponse`'s values; in case of HIT, it's a string value, and in vase of MISS, it's `null` (currently this is called `valuesArray`)

2. an array containing field/value pairs, which I named `fieldValueDictionary`.

For 1, I think we can keep the name as is. Or we can rename this to responses to align with our .NET SDK, although it doesn't follow the value<type> naming convention. For 2, I wanted to hear your opinion. I chose fieldValueDictionary because I wanted to differentiate it from valuesArray since it contains field/value pairs compared to just values. How about fieldStringValueStringArray to represent a content inside? This suggestion will be changed depending on our decision for 1.

The .NET SDK is returning responses without extracting values from them in a Responses property. There are also methods for returning the extracted values of responses as a list of strings or a list of byte arrays. It doesn't return key/value pairs anywhere. We need to do the same. Like Chris suggested, the function returning the list of responses should just be called responses, and the list of extracted values should be called valuesString().

@cprice404 @malandis can you sanity check me here please?

My intention for this API is that there will only be two accessors on this response type after we make the changes:

  1. A values dictionary
  2. An array containing the raw responses (values not extracted, so no .value prefix necessary)

In .NET we will be removing the methods/properties for "accessing the extracted values as a list of strings or as a list of byte arrays".

@poppoerika
Copy link
Contributor Author

@pgautier404 @cprice404 We want to return two values from dictionaryGetFields (which is dictionaryGetBatch in this branch still)

1. an array containing `CacheDictionaryGetResponse`'s values; in case of HIT, it's a string value, and in vase of MISS, it's `null` (currently this is called `valuesArray`)

2. an array containing field/value pairs, which I named `fieldValueDictionary`.

For 1, I think we can keep the name as is. Or we can rename this to responses to align with our .NET SDK, although it doesn't follow the value<type> naming convention. For 2, I wanted to hear your opinion. I chose fieldValueDictionary because I wanted to differentiate it from valuesArray since it contains field/value pairs compared to just values. How about fieldStringValueStringArray to represent a content inside? This suggestion will be changed depending on our decision for 1.

The .NET SDK is returning responses without extracting values from them in a Responses property. There are also methods for returning the extracted values of responses as a list of strings or a list of byte arrays. It doesn't return key/value pairs anywhere. We need to do the same. Like Chris suggested, the function returning the list of responses should just be called responses, and the list of extracted values should be called valuesString().
@cprice404 @malandis can you sanity check me here please?

My intention for this API is that there will only be two accessors on this response type after we make the changes:

  1. A values dictionary
  2. An array containing the raw responses (values not extracted, so no .value prefix necessary)

In .NET we will be removing the methods/properties for "accessing the extracted values as a list of strings or as a list of byte arrays".

Got it.
I don't recall why I created valuesArray to only return values instead of responses...
I will update to the following:

  • responses which contain the raw responses
  • valuesArray which contains key/value pairs. Same as dictionary method from dictionaryFetch.

Should I use dictionary instead of valuesArray although dictionary is not a type in PHP?
If we decided to use valuesArray, I'd like to rename dictionary in dictionaryFetch to be consistent.

@cprice404
Copy link
Contributor

Should I use dictionary instead of valuesArray although dictionary is not a type in PHP?

It should start with values either way. valuesDictionary makes more sense to me but it might not for folks more experienced with PHP. @pgautier404 wdyt?

@pgautier404
Copy link
Collaborator

Should I use dictionary instead of valuesArray although dictionary is not a type in PHP?

It should start with values either way. valuesDictionary makes more sense to me but it might not for folks more experienced with PHP. @pgautier404 wdyt?

I honestly couldn't speak for PHP devs other than myself, but I would personally prefer valuesDictionary and appreciate the hint about which of the polymorphic PHP array types I was supposed to be getting. When I type $response->asHit()->v I think the completion should help document how to handle the value type.

@poppoerika poppoerika requested a review from cprice404 November 16, 2022 05:46
$this->responsesList[] = new CacheDictionaryGetFieldResponseMiss();
$this->responses[] = new CacheDictionaryGetFieldResponseHit(null, $response->getCacheBody());
$this->valuesDictionary[$fields[$counter]] = $response->getCacheBody();
$counter++;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd like to ask you about this counter and about the numRequested param.

Comment on lines 578 to 581
if ($dictionaryGetFieldsResponse->hasFound()) {
return new CacheDictionaryGetFieldsResponseSuccess($dictionaryGetFieldsResponse, fields: $fields);
}
return new CacheDictionaryGetFieldsResponseSuccess(null, count($fields));
Copy link
Collaborator

@pgautier404 pgautier404 Nov 16, 2022

Choose a reason for hiding this comment

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

This should be returning CacheDictionaryGetFieldsResponseHit and CacheDictionaryGetFieldsResponseMiss instead of trying to use the Success class to represent two different states.

Comment on lines 1005 to 1007
if (is_null($responses) && !is_null($numRequested)) {
foreach (range(0, $numRequested - 1) as $ignored) {
$this->responsesList[] = new CacheDictionaryGetFieldResponseMiss();
$this->responses[] = new CacheDictionaryGetFieldResponseMiss();
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think all of this is the result of trying to use a Success class where we need to be using Hit and Miss classes instead. I left a comment on _ScsDataClient that lines up with this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When I moved CacheDicitonaryGetBatch from our .NET incubating repo, I referenced here, which has Success and Error as CacheDictionaryGetBatchResponse.
Sorry if I missed, but are we going to update this response type to Hit, Miss, and Error instead?

Copy link
Collaborator

Choose a reason for hiding this comment

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

You might double check with @cprice404 but I think this should follow the Hit/Miss/Error pattern since we're dealing with a single dictionary value and we can tell if our request was a miss in the corresponding data client code. It should also allow us to get rid of the $numRequested parameter and logic in the CacheDictionaryGetFieldsResponseSuccess constructor.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I agree with @pgautier404 , I think this was an oversight when we were switching the .NET SDK over.

Here:

https://github.com/momentohq/client-sdk-dotnet-incubating/blame/main/src/Momento.Sdk.Incubating/Internal/ScsDataClient.cs#L312

That code does not check for the "Missing" case that we got from the server. My gut is that it should be checking for that case, and should use Hit/Miss/Error pattern instead of success. That's what we do for DictionaryFetch, ListFech, etc. So we should fix that both in .NET and PHP. I created this ticket to capture it for .NET momentohq/client-sdk-dotnet-incubating#47 but yes let's go ahead and make this change here. @malandis if you know of any reason why DictionaryGetBatch/DictionaryGetFields shouldn't use Hit/Miss/Error pattern let us know.

I didn't review this closely enough to understand why that change would eliminate the need for the numRequested/counter thing but I also agree that it seems like we shouldn't need those, so if they still seem necessary after the switch to Hit/Miss/Error feel free to ping for 👀 .

Sorry for not catching this during the .NET work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pgautier404 @cprice404 @malandis
My understanding is we want to have 4 different response patters:

  1. We found a dictionary and all items in the dictionary also found.
  2. We found a dictionary but some of the items in the dictionary are missing.
  3. We did not find a dictionary.
  4. We had an error finding a dictionary.

Cases 1, 3, 4 are straightforward.
1 -> Hit
3 -> Miss
4 -> Error

But how about case 2? Would this be Hit although some of the items are Miss?
So Hit means that finding a dictionary not necessarily the items inside?

Copy link
Contributor

Choose a reason for hiding this comment

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

yes my opinion is that if the Dictionary itself is found, then case 2 is a HIT.

users may then check for individual fields by iterating over the responses and seeing which are HIT vs MISS, or they can just use valueDictionary and check to see if each key exists.

Comment on lines 999 to 1000
$counter = 0;
parent::__construct();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Kind of a nit, but the call to the parent constructor should pretty much always be the first line in a function:

Suggested change
$counter = 0;
parent::__construct();
parent::__construct();
$counter = 0;

if ($response->getResult() == ECacheResult::Hit) {
$this->responses[] = new CacheDictionaryGetFieldResponseHit(null, $response->getCacheBody());
$this->valuesDictionary[$fields[$counter]] = $response->getCacheBody();
} else if ($response->getResult() == ECacheResult::Miss) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

My IDE is telling me that PHP standards prefer elseif.

Suggested change
} else if ($response->getResult() == ECacheResult::Miss) {
} elseif ($response->getResult() == ECacheResult::Miss) {

@pgautier404
Copy link
Collaborator

I left a couple of notes on really minor changes but am good for this to merge once you have a chance to look at those!

Copy link
Collaborator

@pgautier404 pgautier404 left a comment

Choose a reason for hiding this comment

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

LGTM!

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.

🚢

@poppoerika poppoerika merged commit 1a1e86c into main Nov 17, 2022
@malandis malandis deleted the chore/dictionary-get-batch-return-array branch November 1, 2024 21:19
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.

DictionaryGetBatch should return a dictionary
3 participants