Skip to content

JdbcOperationsSessionRepository: deserialize lazily #1133

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

Closed

Conversation

candrews
Copy link
Contributor

Instead of deserializing all of the session attributes as they are read from the database, deserialize as getAttribute(String) requests them.
For applications which store a lot of data in the session but only use some of it for each requests, this change results in a lot less time being spent doing deserialization of objects that won't be used.
For other applications, no harm is done.

@candrews
Copy link
Contributor Author

The same solution could be applied to RedisOperationsSessionRepository too (I can do that if this approach is deemed acceptable)

@candrews
Copy link
Contributor Author

@vpavic what do you think?

@vpavic vpavic self-assigned this Aug 1, 2018
@vpavic
Copy link
Contributor

vpavic commented Aug 1, 2018

Thanks for the PR @candrews, we'll review and consider this for 2.1.x.

@vpavic vpavic added this to the 2.1.0.M2 milestone Aug 1, 2018
Copy link
Contributor

@vpavic vpavic left a comment

Choose a reason for hiding this comment

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

This is something we'd like to get merged in one of the 2.1.0 milestones. I've left one comment on what I believe could be simplified.

Other than that, could you please:

  • rebase on the current master
  • provide some unit tests that verified the new behavior

@@ -757,7 +800,7 @@ public void setAttribute(String attributeName, Object attributeValue) {
? oldDeltaValue
: DeltaValue.UPDATED);
}
this.delegate.setAttribute(attributeName, attributeValue);
this.delegate.setAttribute(attributeName, constantSupplier(attributeValue));
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this really necessary? I think we could set attribute here as is, define our own Supplier and use it in SessionResultSetExtractor. JdbcSession#getAttribute would then test if the attribute is instance of the supplier we defined and if yes execute #get on it. That would reduce the impact and simplify things.

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 initially thought of that approach as well, but decided not to go with it. My reasons are:

  • I believe instanceof checking is generally discouraged in favor of polymorphism (which is what I ended up doing)
  • That would prohibit the storage of instances of that special class (as doing so would result in unintended behavior)

Would you still like me to go ahead with that approach?

@vpavic vpavic modified the milestones: 2.1.0.M2, 2.1.0.M3 Aug 20, 2018
Instead of deserializing all of the session attributes as they are read from the database, deserialize as getAttribute(String) requests them.
For applications which store a lot of data in the session but only use some of it for each requests, this change results in a lot less time being spent doing deserialization of objects that won't be used.
For other applications, no harm is done.
@candrews candrews force-pushed the jdbc-wait-deserialize branch from 236b88e to 5cb6ac1 Compare August 23, 2018 23:55
@candrews
Copy link
Contributor Author

rebase on the current master

✔️

provide some unit tests that verified the new behavior

I'm having a bit of trouble with that. SessionResultSetExtractor seems like it would be the part to test (it's currently not executed by any of the unit tests). However, it's a private class so it can't be accessed directly, and jdbcOperations.query is always mocked (running the actual thing would result in a real database connection being made, which is not unit-testy and wouldn't work). Do you have any suggestions on what you'd like to see?

@candrews
Copy link
Contributor Author

Also, it occurs to me that the existing integration tests (which pass) show that this change doesn't break anything.

@vpavic
Copy link
Contributor

vpavic commented Sep 3, 2018

Thanks for the update @candrews.

I'm having a bit of trouble with that.

You could look into supplying a custom ConversionService and then verify its invocations. Does that make sense?

Also, it occurs to me that the existing integration tests (which pass) show that this change doesn't break anything.

We are introducing a new behavior here, and we should verify that in our tests.

@vpavic vpavic added the status: waiting-for-feedback We need additional information before we can continue label Sep 3, 2018
@candrews
Copy link
Contributor Author

candrews commented Sep 4, 2018

You could look into supplying a custom ConversionService and then verify its invocations. Does that make sense?

That was my first thought, too, but I can't figure out a way to make that happen.

conversionService is used in org.springframework.session.jdbc.JdbcOperationsSessionRepository.deserialize(byte[]), which is called from org.springframework.session.jdbc.JdbcOperationsSessionRepository.SessionResultSetExtractor.extractData(ResultSet) - and as far as I can tell, there's no way to get SessionResultSetExtractor.extractData(ResultSet) to execute (see #1133 (comment)).

@vpavic vpavic modified the milestones: 2.1.0.M3, 2.1.0.RC1 Sep 10, 2018
@vpavic vpavic removed the status: waiting-for-feedback We need additional information before we can continue label Sep 19, 2018
vpavic pushed a commit that referenced this pull request Sep 19, 2018
Instead of deserializing all of the session attributes as they are read from the database, deserialize as #getAttribute requests them.

See: #1133
@vpavic vpavic closed this in b61937d Sep 19, 2018
@vpavic
Copy link
Contributor

vpavic commented Sep 19, 2018

This is now merged to master in c523fb5 and polished in b61937d.
Thanks for the PR @candrews - please review the polish commit and the approach taken to verify the new behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: jdbc type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants