XWIKI-15455 </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 < [email protected]>: > 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 < > [email protected]>: > >> Corresponding JIRA issue: https://jira.xwiki.org/browse/XWIKI-15445 >> >> 2018-07-18 11:07 GMT+02:00 Guillaume Delhumeau < >> [email protected]>: >> >>> 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 ([email protected]) >> Research & Development Engineer at XWiki SAS >> Committer on the XWiki.org project >> > > > > -- > Guillaume Delhumeau ([email protected]) > Research & Development Engineer at XWiki SAS > Committer on the XWiki.org project > -- Guillaume Delhumeau ([email protected]) Research & Development Engineer at XWiki SAS Committer on the XWiki.org project

