Skip to content
This repository has been archived by the owner on Aug 19, 2019. It is now read-only.

Miscellaneous cleanup. #43

Merged
merged 6 commits into from
Dec 19, 2017
Merged

Miscellaneous cleanup. #43

merged 6 commits into from
Dec 19, 2017

Conversation

igorpeshansky
Copy link
Member

  • Throw an exception on parse errors.
  • Allow parsing JSON streams with multiple objects.
  • Factor out streaming operators for request/response headers.
  • Remove superfluous std::bind calls.

@igorpeshansky
Copy link
Member Author

@supriyagarg, you might want to review as well.

src/json.cc Outdated
if (all_values.size() > 1) {
std::ostringstream out;
out << "Getting a single value out of " << all_values.size();
throw json::Exception(out.str());
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this really be an exception instead a warning?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, I want this to be an error. This really means an expectation mismatch, and I don't want to drop the other values with just a bit of log spam.

Copy link
Contributor

@bmoyles0117 bmoyles0117 Dec 19, 2017

Choose a reason for hiding this comment

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

Previously we only had the option to fetch a single value and that would either return the value or return a nullptr. The contract has changed since then, is there any code that would be negatively impacted by this? If so, have those already been surrounded by the appropriate try / catch blocks?

Copy link
Member Author

Choose a reason for hiding this comment

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

Let's keep the two separate. Previously, we only queried endpoints that would return a single JSON object at a time, so this should be fully backward compatible. We also used to return nullptr in case of a parse error, and now we throw an exception, but all those uses have been updated as part of this PR.
To answer @qingling128's comment, the old API always parsed a single value. The new implementation parses a vector of values. However, when only a single value is requested, we want to validate the input by ensuring that the parsed vector is a singleton. I've updated the error message.

Choose a reason for hiding this comment

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

I'm a bit confused reading this part as well. So we take a vector and want to make sure it has exactly one element? If so, shouldn't the exception message Getting a single value out of be changed to Getting more than one value out of instead?

Choose a reason for hiding this comment

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

Thanks for changing the error message. LGTM now.

static std::unique_ptr<Value> FromStream(std::istream& stream);
static std::unique_ptr<Value> FromString(const std::string& input);
static std::vector<std::unique_ptr<Value>> AllFromStream(
std::istream& stream) throw(Exception);
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we limit the throw to a json::Exception?

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 is json::Exception. This code is within the json namespace.

Copy link
Contributor

@bmoyles0117 bmoyles0117 Dec 19, 2017

Choose a reason for hiding this comment

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

Ahh I was confused, why is it that we need to include json:: here despite also being in the json namespace?

throw json::Exception("There is no " + field + " in " + ToString());

Copy link
Member Author

Choose a reason for hiding this comment

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

That was a typo. Fixed (there and in json.cc).

Copy link
Member Author

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

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

Responded. PTAL.

src/json.cc Outdated
if (all_values.size() > 1) {
std::ostringstream out;
out << "Getting a single value out of " << all_values.size();
throw json::Exception(out.str());
Copy link
Member Author

Choose a reason for hiding this comment

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

No, I want this to be an error. This really means an expectation mismatch, and I don't want to drop the other values with just a bit of log spam.

static std::unique_ptr<Value> FromStream(std::istream& stream);
static std::unique_ptr<Value> FromString(const std::string& input);
static std::vector<std::unique_ptr<Value>> AllFromStream(
std::istream& stream) throw(Exception);
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 is json::Exception. This code is within the json namespace.

JSONBuilder builder;

const int kMax = 65536;
unsigned char data[kMax];
yajl_handle handle = yajl_alloc(&callbacks, NULL, (void*) &builder);
yajl_config(handle, yajl_allow_comments, 1);
yajl_config(handle, yajl_allow_multiple_values, 1);
//yajl_config(handle, yajl_allow_trailing_garbage, 1);

Choose a reason for hiding this comment

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

Are we commenting out these two lines on purpose? If so, maybe leave a comment for the reason and under what circumstances we might want to uncomment them?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. These were robustness changes that would allow us to talk to less formalized APIs. I decided we should instead do some validation on the Kubernetes API, but if it turns out to be buggy or unstable, we may end up uncommenting these.
I thought that the option names (allow_trailing_garbage and dont_validate_strings) were self-descriptive enough that they didn't merit a separate comment.

Choose a reason for hiding this comment

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

Ah, I see. Now I understand.

src/json.cc Outdated
if (all_values.size() > 1) {
std::ostringstream out;
out << "Getting a single value out of " << all_values.size();
throw json::Exception(out.str());

Choose a reason for hiding this comment

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

I'm a bit confused reading this part as well. So we take a vector and want to make sure it has exactly one element? If so, shouldn't the exception message Getting a single value out of be changed to Getting more than one value out of instead?


namespace google {

// Allow logging request headers.

Choose a reason for hiding this comment

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

What does "allow" mean in this context? The method seems straight forward though.

Copy link
Member Author

Choose a reason for hiding this comment

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

It means "enable" -- without this method, using log << req.headers() would fail to compile. However, "enable" is overloaded (e.g., could mean a config option), so I went with a more neutral word.

Choose a reason for hiding this comment

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

Ah, I see. Thanks for the clarification.

Copy link
Member Author

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

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

Addressed feedback. PTAL.

src/json.cc Outdated
if (all_values.size() > 1) {
std::ostringstream out;
out << "Getting a single value out of " << all_values.size();
throw json::Exception(out.str());
Copy link
Member Author

Choose a reason for hiding this comment

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

Let's keep the two separate. Previously, we only queried endpoints that would return a single JSON object at a time, so this should be fully backward compatible. We also used to return nullptr in case of a parse error, and now we throw an exception, but all those uses have been updated as part of this PR.
To answer @qingling128's comment, the old API always parsed a single value. The new implementation parses a vector of values. However, when only a single value is requested, we want to validate the input by ensuring that the parsed vector is a singleton. I've updated the error message.

static std::unique_ptr<Value> FromStream(std::istream& stream);
static std::unique_ptr<Value> FromString(const std::string& input);
static std::vector<std::unique_ptr<Value>> AllFromStream(
std::istream& stream) throw(Exception);
Copy link
Member Author

Choose a reason for hiding this comment

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

That was a typo. Fixed (there and in json.cc).


namespace google {

// Allow logging request headers.
Copy link
Member Author

Choose a reason for hiding this comment

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

It means "enable" -- without this method, using log << req.headers() would fail to compile. However, "enable" is overloaded (e.g., could mean a config option), so I went with a more neutral word.

JSONBuilder builder;

const int kMax = 65536;
unsigned char data[kMax];
yajl_handle handle = yajl_alloc(&callbacks, NULL, (void*) &builder);
yajl_config(handle, yajl_allow_comments, 1);
yajl_config(handle, yajl_allow_multiple_values, 1);
//yajl_config(handle, yajl_allow_trailing_garbage, 1);
Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. These were robustness changes that would allow us to talk to less formalized APIs. I decided we should instead do some validation on the Kubernetes API, but if it turns out to be buggy or unstable, we may end up uncommenting these.
I thought that the option names (allow_trailing_garbage and dont_validate_strings) were self-descriptive enough that they didn't merit a separate comment.

Copy link

@qingling128 qingling128 left a comment

Choose a reason for hiding this comment

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

LGTM.


namespace google {

// Allow logging request headers.

Choose a reason for hiding this comment

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

Ah, I see. Thanks for the clarification.

JSONBuilder builder;

const int kMax = 65536;
unsigned char data[kMax];
yajl_handle handle = yajl_alloc(&callbacks, NULL, (void*) &builder);
yajl_config(handle, yajl_allow_comments, 1);
yajl_config(handle, yajl_allow_multiple_values, 1);
//yajl_config(handle, yajl_allow_trailing_garbage, 1);

Choose a reason for hiding this comment

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

Ah, I see. Now I understand.

src/json.cc Outdated
if (all_values.size() > 1) {
std::ostringstream out;
out << "Getting a single value out of " << all_values.size();
throw json::Exception(out.str());

Choose a reason for hiding this comment

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

Thanks for changing the error message. LGTM now.

Copy link
Contributor

@bmoyles0117 bmoyles0117 left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@supriyagarg
Copy link
Contributor

LGTM

@igorpeshansky igorpeshansky merged commit 357355b into master Dec 19, 2017
@igorpeshansky igorpeshansky deleted the igorp-miscellaneous-cleanup branch December 19, 2017 23:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants