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

Reduce memory usage when returning large result sets #147

Merged
merged 7 commits into from
Feb 14, 2017

Conversation

Azquelt
Copy link
Member

@Azquelt Azquelt commented Feb 13, 2017

When returning large resultsets, stream assets one by one from the database to the response without holding the entire response in memory.

Also includes a tiny bit of reformatting
return results;

AssetCursor result = new MongoAssetCursor(cursor);
result.addOperation(CONVERT_OID_TO_HEX);
Copy link
Member

Choose a reason for hiding this comment

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

Both places we currently the new MongoAssetCursor, we add the convert operation. would it make sense to have a factory for this? MongoAssetCursor.newCursorWithIdConversion(cursor) or similar?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, possibly? Or I could put this functionality into MongoAssetCursor itself on the basis that we will always need to convert the id when turning a MongoDB record into an asset.

On the other hand, it fits quite nicely into an operation.

}

@Override
public void remove() {
Copy link
Member

Choose a reason for hiding this comment

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

Don't think there is any use-case for this, but isn't 'remove' supported by the map iterator?

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 is, but it's not supported in the MongoAssetCursor, so there doesn't seem much point implementing it in the test implementation

*
* @return the number of assets
*/
public int getCount();
Copy link
Member

Choose a reason for hiding this comment

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

any reason why you called this getCount? It seems to replace a method call to 'size' in lots of places, and wraps a call to 'size' in the case of the mongo cursor.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really, getCount() made sense to me when writing it, but you're correct that other objects use size()

Copy link
Member Author

Choose a reason for hiding this comment

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

For added confusion, DBCursor has length(), count() and size() which all do different things


/** {@inheritDoc} */
@Override
public void writeTo(AssetCursor cursor, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
Copy link
Member

Choose a reason for hiding this comment

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

You're not checking the mediatype here. At this point, do we just have to assume that jax-rs has called the above method and is giving us something sensible?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, that was what I was assuming

Newer version of Eclipse wants to reformat this class when I save, so
let's separate the reformatting changes into another commit.
This change allows results to be streamed from the database into a
response to the client when retrieving multiple assets. It avoids
needing to load the whole result set into memory before returning it.

To do this we introduce the AssetCursor, which wraps a database result
cursor and allows the Rest layer to iterate through the results without
needing to know the details of the persistence backend.

To allow changes to be made to the information from the database before
it is consumed by the rest layer we introduce the AssetOperation, which
encapsulates some processing which should be done to the asset before it
is returned (e.g. transforming between data types or removing
implementation-specific fields)
With the introduction of AssetCursor, AssetList is now only used for
tests.
Make AssetCursor implement Closable, and then read the AssetCursor
within a try-with-resources so that it gets closed.
@Azquelt
Copy link
Member Author

Azquelt commented Feb 13, 2017

I checked and we do have a check to ensure the search match score is not returned in the response. It's at the end of PersistenceBeanTest.testRetrieveAllFiltered()

Copy link
Member

@idlewis idlewis left a comment

Choose a reason for hiding this comment

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

Ok

@idlewis idlewis merged commit 913e3db into WASdev:master Feb 14, 2017
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