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

NGSIv2 rendering improvements (simplification, unification and performance) #3285

Merged
merged 12 commits into from
Sep 12, 2018

Conversation

fgalan
Copy link
Member

@fgalan fgalan commented Sep 5, 2018

This PR is motivated by #1298 (comment) and introduces improvements in NGSIv2 rendering logic in both simplfication/unification and peformance aspects. A summary of changes follow.

With regards to simplification/unification:

  • Extend JsonHelper utilization along NGSIv2 rendering logic
  • Simplification in several methods, mainly:
    • CompoundValueNode::toJson()
    • Entity::toJson() (spliting in several other methods)
    • ContextAttribute::toJson()
    • ContextAttributeVector:.toJson() (removed)
    • MetadataVector::toJson() (the usage of JsonHelper removes the need of double-pass)
  • Simplification in argument passing. In particular, bool comma removed whenever possible
  • Removing stale code.

With regards to peformance:

  • JsonHelper implemention changed from std::ostringstream to std::string concatenation (as in previous NGSIv2 renderind code for entities). After the changes in this PR, I think std::ostringstream is no longer used in any part of the CB code.
  • Logic in the toJson() methods has been simplified.
  • I have done some basic ab testing with render intenstive operations (GET /v2/entities?limit=1000 and GET /v2/subscriptions?limit=1000, which 500 bytes entities/subscription, i.e. ~50KB in each GET response). The details of the test are here for master and here for this branch, but, in summary the result is pretty good:
    • Entities rendering test: from 77.22 tps to 103.06 tps (33.46% gain)
    • Subscriptions renderint test: 25.73 tps from to 119.75 tps (365.4% gain)

(The script used to populate the database can be found here. Eventually, it would be added to the repository for future usage)

From my point of view, this PR doesn't completes #1298 and more could to be done with regards to simplification and unification (for instance, ContextElement should use Entity internally and this will simplify a lot removing all the specific ContextElement rendering code) and peformance (other implementation alternatives for JsonHelper.cpp could be explored) but I think is an important step ahead.

Note, there are some changes in .test but all there seem to be ok. See specific comments in .test files.

@@ -29,6 +29,7 @@
#include "common/errorMessages.h"
Copy link
Member Author

Choose a reason for hiding this comment

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

CNR entries missing

(Self-node)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in a99e4d6

}

template <> std::string toString(float f);
extern std::string double2string(double f);
Copy link
Member Author

Choose a reason for hiding this comment

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

toString() was pretty generic... I think that double2string() is more clear.

Copy link
Member

Choose a reason for hiding this comment

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

Definitely.

NTC

@@ -155,4 +155,4 @@ Date: REGEX(.*)
brokerStop CB
accumulatorStop ${LISTENER_PORT}
accumulatorStop ${LISTENER2_PORT}
#dbDrop CB
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 did a general look for #dbDrop CB while I was testing and discover this old one. I have take the opportunity to fix it.

NTC (only informative)

@@ -462,6 +462,11 @@ Fiware-Correlator: REGEX([0-9a-f\-]{36})
"type": "Text",
"value": "bar"
},
"dateModified": {
Copy link
Member Author

Choose a reason for hiding this comment

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

Old implemenation was buggy and dateModified were not included in the notification. After render changes, the bug has been solved, so this .test is changing.

Copy link
Member Author

Choose a reason for hiding this comment

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

NTC (I guess)

Copy link
Member

Choose a reason for hiding this comment

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

NTC

@@ -58,7 +58,7 @@ echo
echo


echo "02. GET /v2/entities/E!/attrs/a_string/value"
echo "02. GET /v2/entities/E1/attrs/a_string/value"
Copy link
Member Author

Choose a reason for hiding this comment

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

Small typo in echo line, now fixed.

Copy link
Member Author

Choose a reason for hiding this comment

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

NTC (I guess)

Copy link
Member

Choose a reason for hiding this comment

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

NTC

@@ -217,7 +217,7 @@ echo
01. Second call to GET /statistics (gives time stat of FIRST request for /statistics)
=====================================================================================
HTTP/1.1 200 OK
Content-Length: 127
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 was having problems with Content-Length of statistics and metrics text. For instance, I see that 0.71234 changed to 0.6223 which stills matching the REGEX() for that value, but reduce the Content-Length in 1.

In general, Content-Length in statistics/metrics test is not very important. In fact, I have already seen many Content-Length: REGEX(.*) and Content-Length: REGEX(\d+). Thus, I understand the similar changes in this PR are ok.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, no reason to include the exact Content-Length. the payload is there to be compared. more than enough.

NTC

@@ -279,13 +279,13 @@ Fiware-Correlator: REGEX([0-9a-f\-]{36})
"A": {
"metadata": {
"previousValue": {
"toplevel": [
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 funny! :)

It seems we have a bug in compound metadata rendeering logic. With the new implementaiton of the renders, now seems to be fixed and this .test has been modified to align with it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fix mentioned in CNR

NTC (I guess)

Copy link
Member

Choose a reason for hiding this comment

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

NTC

Copy link
Member

@kzangeli kzangeli left a comment

Choose a reason for hiding this comment

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

Looks very good.
Just a few minor comments

{
// Reorder attributes in the same order they are in attrsFilter, excluding the ones
// note there (i.e. filtering them out) and giving special treatment to creation
// and modification dates
Copy link
Member

Choose a reason for hiding this comment

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

excluding the ones note there ...

Difficult to understand this phrase.
Is it supposed to be "excluding the ones *not * there"?
Doesn't make too much sense. Can't exclude something that is already not present ...

Perhaps:
"except those that aren't present, of course ..."

Copy link
Member Author

Choose a reason for hiding this comment

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

Rewritten in 295296b

}
}

// All the remainder elements in attributeVector need to be released,
Copy link
Member

Choose a reason for hiding this comment

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

remainder -> remaining?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

if (found != -1)
{
caNewV.push_back(attributeVector.vec[found]);
attributeVector.vec.erase(attributeVector.vec.begin() + found);
Copy link
Member

Choose a reason for hiding this comment

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

Is this necessary?
Later, "attributeVector.release();" should take care of all of it, 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.

If we don't erase() from the original vector, then the same caP will be pointed from two places (the old vector and the new vector) so it will freed twice, causing a double free.

I have a valgrind run in place to confirm if there is something wrong with regards to memory management in the current implementation.

Copy link
Member

Choose a reason for hiding this comment

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

ok, I guess ...
NYC

}
}

// Legacy support for options=dateCreated and opations=dateModified
Copy link
Member

Choose a reason for hiding this comment

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

Typo: options?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

attributeVector.push_back(caP);
}

// Removing dateExpires if not explictely included in the filter
Copy link
Member

Choose a reason for hiding this comment

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

Typo: explictely

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

@@ -507,15 +339,15 @@ void ContextAttributeVector::fill(ContextAttributeVector* cavP, bool useDefaultT
*
* lookup -
*/
ContextAttribute* ContextAttributeVector::lookup(const std::string& attributeName) const
int ContextAttributeVector::lookup(const std::string& attributeName) const
Copy link
Member

Choose a reason for hiding this comment

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

A better name of this method would be 'index' or 'getIndex'.
'lookup' indicates to actually return what was looked up ...

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 point. Chaning name.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

}
}

// Removing dateExpires if not explictely included in the filter
Copy link
Member

Choose a reason for hiding this comment

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

typo: explicitly

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

}

return out;
return jh.str();
}
Copy link
Member

Choose a reason for hiding this comment

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

Truly great would be to have an input parameter "JsonHelper* jhP" to all these rendering functions, instead of returning objects on the stack ...

NTC, but ... perhaps in a future modification? ;-)

Copy link
Member Author

@fgalan fgalan Sep 5, 2018

Choose a reason for hiding this comment

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

You mean to have a single instance of JsonHelper per rendered tree passing it down along the tree?

An interesting idea, although it should be explored in terms of complexity / performance gain. Perhaps in the future...

Copy link
Member

Choose a reason for hiding this comment

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

Yes, one single JsonHelper per response. that would be good.
As you say, perhaps in the future ...
Issue?

NTC


if (container != NULL)
switch(valueType)
Copy link
Member

Choose a reason for hiding this comment

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

Space missing. 'switch' is not a function ...

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed in 295296b

@@ -217,7 +217,7 @@ echo
01. Second call to GET /statistics (gives time stat of FIRST request for /statistics)
=====================================================================================
HTTP/1.1 200 OK
Content-Length: 127
Copy link
Member

Choose a reason for hiding this comment

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

yeah, no reason to include the exact Content-Length. the payload is there to be compared. more than enough.

NTC

@kzangeli
Copy link
Member

kzangeli commented Sep 6, 2018

LGTM (assuming valgrind reports no leaks)

@fgalan
Copy link
Member Author

fgalan commented Sep 7, 2018

Some additional changes were required after LGTM, due to memory management issues. The new changes can be seen at 6eafb3f...7a31172

@@ -38,8 +38,8 @@ payload='{
}
],
"attributes": [
"temperature",
"ligthstatus"
"ligthstatus",
Copy link
Member Author

Choose a reason for hiding this comment

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

With the changes in 6eafb3f...7a31172 the "attributes" vector now defines the order of the attributes as they have to appear in the response. I see this as a little improvement, but the .test needs this slight adjust.

Copy link
Member

@kzangeli kzangeli left a comment

Choose a reason for hiding this comment

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

LGTM

@AlvaroVega AlvaroVega merged commit 8f2e123 into master Sep 12, 2018
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