2018-07-25 16:14 GMT+02:00 Guillaume Delhumeau < guillaume.delhum...@xwiki.com>:
> After more thinking and discussions with Thomas, it appears solution B > (creating a table with Hibernate) is the only valuable option. These > preferences are not real data that would need to be stored on the user > page. They are "temporary" configurations for each user. > > In addition, it would permit to optimize the HQL query by linking elements > of the 2 tables instead of introducing 700 "OR location = xxx". This > optimization is actually not a nice-to-have thing, but a real requirement > for scalability. > As a drawback, it means users' configurations would not be exportable in a XAR like the rest of the content... > 2018-07-20 21:05 GMT+03:00 Guillaume Delhumeau < > guillaume.delhum...@xwiki.com>: > >> XWIKI-15455 <http:///browse/XWIKI-15455> (that I have just created) >> invalidates both Solution A and C since it requires to store a Date along >> with each location, so we cannot store several locations in the same >> Notification Filter Preferences object. >> >> 2018-07-19 11:03 GMT+02:00 Guillaume Delhumeau < >> guillaume.delhum...@xwiki.com>: >> >>> FYI, I'll continue with the solution A, which is very close to solution >>> C, and I'll try to use the less memory possible. >>> >>> 2018-07-18 11:27 GMT+02:00 Guillaume Delhumeau < >>> guillaume.delhum...@xwiki.com>: >>> >>>> Corresponding JIRA issue: https://jira.xwiki.org/browse/XWIKI-15445 >>>> >>>> 2018-07-18 11:07 GMT+02:00 Guillaume Delhumeau < >>>> guillaume.delhum...@xwiki.com>: >>>> >>>>> Hi. >>>>> >>>>> [TL;DR] >>>>> >>>>> This thread is about the way we store notification filter preferences >>>>> for each user. The constraint is there can be a lot of them (700 is a >>>>> number a user has recently reported). So how should we store them? >>>>> >>>>> [Full text] >>>>> >>>>> = Definition = >>>>> >>>>> So what is a filter preference? It's a generic object that can store >>>>> many elements, such as a page locations, application names, event types, >>>>> etc... They describe a configuration about a given filter for a given >>>>> user. >>>>> For example, a filter preference can say "for the ScopeNotificationFilter >>>>> and the user A, include the location Main.WebHome" as it could be "for the >>>>> UserNotificationFilter and the user A, exclude the user SPAM". It's >>>>> generic. >>>>> >>>>> The main usage is for page locations (ScopeNotificationFilter). By >>>>> default, we have the "autowatch" mode enabled. It means every time a user >>>>> modifies a page, a filter preference for this page and this user is >>>>> created. So if a user modifies 700 pages, he gets 700 filter preferences. >>>>> >>>>> = How are they stored = >>>>> >>>>> Currently, we have a simple implementation. There is a generic XClass >>>>> called "XWiki.Notifications.Code.NotificationFilterPreferenceClass". >>>>> For each preference, we add an XObject on the user page. It's that simple. >>>>> But it also means that if a users have 700 filter preferences, she also >>>>> gets 700 XObjects on her page, and 700 revisions of that page. Which is a >>>>> pain: it takes a lot of place in the document's cache, and it's heavy to >>>>> load (lot of SQL queries needed). So we have a big problem here. >>>>> >>>>> = Possible solutions = >>>>> >>>>> == A: Minimize the number of xobjects needed for >>>>> ScopeNotificationFilter == >>>>> >>>>> Currently, one location is represented by 1 filter preference. But >>>>> most filter preferences are very similar. They almost all say "for the >>>>> ScopeNotificationFilter, for all event types, for all applications, the >>>>> filter preference is enabled". The only different part is the actual >>>>> location. But the "location" field is itself a LIST stored with the >>>>> "relational storage" option. So we can take advantage of it and store >>>>> similar preferences into 1 single object. >>>>> >>>>> 1 object with 700 locations instead of 700 objects with 1 location. >>>>> >>>>> However, it's a bit harder than this. Event if the >>>>> NotificationFilterPreferences is generic and can contains many locations, >>>>> the ScopeNotificationFilter expect it to concern only one location (and >>>>> then it perform complex operations to sort the filters preferences >>>>> according to a hierarchy). The UI in the user profile makes the same >>>>> assumption so it does not handle multiple locations in the same >>>>> preferences >>>>> object. Refactoring this is not simple and cannot be done for 10.6. >>>>> >>>>> === Variation 1: store only 1 xobject, but make the API return 700 >>>>> preferences objects anyway === >>>>> >>>>> This is the variation I am prototyping. Actually it's ok if the >>>>> filters and the UI expect only 1 location into the preferences object. All >>>>> we have to do is to "smash" the xobject into many >>>>> NotificationFilterPreferences objects that we need internally. It would >>>>> simply be the responsibility of the Store to detect similarities and to >>>>> save the minimal amount of XObjects to store a bunch of preferences. >>>>> >>>>> But it means being very smart when loading, creating, updating and >>>>> deleting a preference. Not having one xobject per filter preference >>>>> introduces complexity, and complexity can lead to bugs. Again, according >>>>> to >>>>> the time frame, it's hard to implement. >>>>> >>>>> === Variation 2: use custom mapping === >>>>> >>>>> Probably the easiest solution that would help making less SQL queries. >>>>> The idea is to have a SQL table for notification filter preferences and >>>>> bind the XObjects to that table. It would still use a lot of place in the >>>>> document's cache but be more efficient on the database level. >>>>> >>>>> === Other Problem 1: it still creates page revisions === >>>>> >>>>> As long as we store the filter preferences with xobjects, we create >>>>> page revisions. We can get rid of those by using some internal API to not >>>>> create a revision when we save an xobject but I wonder if it's what users >>>>> want. If a user tries to rollback some changes and don't see all filter >>>>> preferences it concerns, I think it's not very transparent. >>>>> >>>>> === Other Problem 2: Document's cache === >>>>> >>>>> Sometime we load the a user document to get the avatar of the user, >>>>> her name, etc... So we load user documents very frequently, even if the >>>>> user is not connected! Having 700 filters in the document and cache them >>>>> with the document even if we don't need them is a big waste of memory. >>>>> >>>>> == B: Implement a completely new store with Hibernate == >>>>> >>>>> A bit like having a custom mapping. We could create a SQL table and >>>>> implement an API to handle it. Then, no xobjects would be involved. >>>>> >>>>> Some drawbacks: >>>>> * we need to write a custom cache as well. >>>>> * the user cannot modify her preferences using the wiki principles >>>>> (xobjects all the way). >>>>> >>>>> == C: Refactor the UI and the ScopeNotificationFilter so they do not >>>>> assume 1 filter preference = 1 location == >>>>> >>>>> This option is still possible. Probably the best because creating 1 >>>>> filter preferences object per location is an obvious waste of memory. A >>>>> refactoring of the UI is needed anyway, because we currently have no way >>>>> to >>>>> remove a bunch of filter preferences easily (users have to delete the 700 >>>>> filters preferences manually) so we can kill 2 birds with the same stone. >>>>> >>>>> But again, it requires some work. >>>>> >>>>> = Conclusion = >>>>> >>>>> That's it. All possible solutions require development effort that is >>>>> hardly possible to make before 10.6 (and even 10.7, considering I would >>>>> probably be the one implementing it and I'm not fulltime on the subject >>>>> and >>>>> I have holidays soon). >>>>> >>>>> Writing this email helped me to see the problem with perspective. I >>>>> think solution C may be the best. But any opinion is good to hear (except >>>>> if you propose something even more complex than I do :p). >>>>> >>>>> Thanks, >>>>> >>>>> Guillaume >>>>> >>>>> >>>> >>>> >>>> -- >>>> Guillaume Delhumeau (guillaume.delhum...@xwiki.com) >>>> Research & Development Engineer at XWiki SAS >>>> Committer on the XWiki.org project >>>> >>> >>> >>> >>> -- >>> Guillaume Delhumeau (guillaume.delhum...@xwiki.com) >>> Research & Development Engineer at XWiki SAS >>> Committer on the XWiki.org project >>> >> >> >> >> -- >> Guillaume Delhumeau (guillaume.delhum...@xwiki.com) >> Research & Development Engineer at XWiki SAS >> Committer on the XWiki.org project >> > > > > -- > Guillaume Delhumeau (guillaume.delhum...@xwiki.com) > Research & Development Engineer at XWiki SAS > Committer on the XWiki.org project > -- Guillaume Delhumeau (guillaume.delhum...@xwiki.com) Research & Development Engineer at XWiki SAS Committer on the XWiki.org project