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

Fix performance problem at login #464

Merged
merged 9 commits into from
Mar 23, 2017
Merged

Conversation

benjamingeer
Copy link

@benjamingeer benjamingeer commented Mar 21, 2017

This fixes a performance problem caused by the use of MessageUtil.toSource in debugging output in ProjectsResponderV1. Also:

  • Add a configuration option app.triplestore.profile-queries that outputs SPARQL queries and the amount of time they take.
  • Change ResourcesResponderV1SpecContextData to load the expected book context response from a file in JSON format, rather than including it in the source code, to keep IntelliJ IDEA from running out of memory when compiling it. This makes it easier to run a profiler in IntelliJ.
  • Use a UUID instead of the current time when generating a session ID in Authenticator.authenticateCredentials() (Creation of session id on login #290).
  • Use Future.sequence instead of Await.result in PermissionsResponderV1.permissionsDataGetV1().
  • Use Vector and Seq instead of List in PermissionsResponderV1.
  • Move functions for reading and writing text files out of FakeTriplestore and into a utility class, FileUtil.
  • Reformat some code.

I'll document how to profile Knora in VisualVM using its IntelliJ IDEA plugin in another pull request.

Fixes #443.
Fixes #290.

@benjamingeer benjamingeer added the bug something isn't working label Mar 21, 2017
@benjamingeer benjamingeer added this to the Beta Release milestone Mar 21, 2017
@benjamingeer benjamingeer self-assigned this Mar 21, 2017
@tobiasschweizer
Copy link
Contributor

first login immediately after having reloaded the data is still slower, but faster than before.

timing

@benjamingeer
Copy link
Author

Will this be good enough for your production server for now, or do we need to investigate further at the moment?

@@ -29,15 +29,15 @@ object Main extends App with LiveCore with KnoraService {
//Kamon.start()

/* Check and wait until all actors are running */
checkActorSystem
checkActorSystem()
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you do that because the method has side-effects? http://docs.scala-lang.org/style/method-invocation.html

Copy link
Author

Choose a reason for hiding this comment

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

Yes.

Copy link
Author

Choose a reason for hiding this comment

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

IntelliJ pointed it out as a style recommendation.


val arglist = args.toList

if (arglist.contains("loadDemoData")) StartupFlags.loadDemoData send true
if (arglist.contains("allowResetTriplestoreContentOperationOverHTTP")) StartupFlags.allowResetTriplestoreContentOperationOverHTTP send true

/* Start the HTTP layer, allowing access */
startService
startService()
Copy link
Contributor

Choose a reason for hiding this comment

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

see above

Copy link
Author

Choose a reason for hiding this comment

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

Yes.

groupInfo <- (responderManager ? GroupInfoByIRIGetRequest(groupIri, None)).mapTo[GroupInfoResponseV1]
res = (groupInfo.group_info.belongsToProject, groupIri)
} yield res
Await.result(resFuture, 1.seconds)
Copy link
Contributor

Choose a reason for hiding this comment

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

Did that blocking Await have any effect slowing down the application?

Copy link
Author

Choose a reason for hiding this comment

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

Not as far as I could tell.

case response: ResourceContextResponseV1 => compareResourceCompoundContextResponses(received = response, expected = ResourcesResponderV1SpecContextData.expectedBookResourceContextResponse)
case response: ResourceContextResponseV1 =>
val responseAsJson = response.toJsValue
assert(responseAsJson == ResourcesResponderV1SpecContextData.expectedBookResourceContextResponse, "book context response did not match")
Copy link
Contributor

Choose a reason for hiding this comment

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

If I understand correctly, the correct ordering of the dependent pages (according to their seqnum) is part of the query. So a 1:1 comparison is good.

I am just mentioning this because there are some tests in which the results have to be ordered according to the same pattern before they are compared (the ordering does not matter for the correctness of the results).

Copy link
Author

Choose a reason for hiding this comment

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

This test always assumed that the order was fixed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that is absolutely correct. I justed wanted to make sure that this is what we want.

Copy link
Author

Choose a reason for hiding this comment

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

I guess so, since the SPARQL query has:

ORDER BY ?seqnum ?sourceObject ?isPreview

@tobiasschweizer
Copy link
Contributor

Will this be good enough for your production server for now, or do we need to investigate further at the moment?

Do you have any idea what could explain that the first login takes about three times longer than any subsequent one?
Also if a do a second login with another user, it is much faster than the first one.

@benjamingeer
Copy link
Author

I believe that the first login loads and caches data from the triplestore, which is reused in subsequent logins.

@tobiasschweizer
Copy link
Contributor

tobiasschweizer commented Mar 23, 2017

I believe that the first login loads and caches data from the triplestore, which is reused in subsequent logins.

Sounds reasonable. So why couldn't we load that data in the cache when the application is started?

@benjamingeer
Copy link
Author

So why couldn't we load that data in the cache when die application is started?

I guess we could. You'd have to ask @subotic, he wrote this code.

@tobiasschweizer
Copy link
Contributor

Hey @subotic, could we cache data needed for authentication when webapi is started?

@benjamingeer
Copy link
Author

In any case, I suspect that would require a non-trivial reworking of the code, so if we do it, it should be done in another pull request. Meanwhile, can we merge this one?

Copy link
Contributor

@tobiasschweizer tobiasschweizer left a comment

Choose a reason for hiding this comment

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

mörtsch

@tobiasschweizer
Copy link
Contributor

could you make an issue for the caching so we do not forget? thx.

@benjamingeer
Copy link
Author

Opened #468.

@benjamingeer benjamingeer merged commit b78086e into develop Mar 23, 2017
@benjamingeer benjamingeer deleted the wip/performance-debugging branch March 23, 2017 11:25
@subotic
Copy link
Collaborator

subotic commented Mar 23, 2017

Hey @subotic, could we cache data needed for authentication when webapi is started?

We probably could. This would require creating a UserProfileV1 for each registered user and storing it into the cache. But I don't think that this will change anything. When a user is authenticated, then the same thing is executed for the first and any subsequent user.

@subotic
Copy link
Collaborator

subotic commented Mar 23, 2017

I will move my last comment to the new issue.

@benjamingeer benjamingeer mentioned this pull request Jul 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Timeout at login Creation of session id on login
4 participants