Bonjour à tous,
Je planche depuis un moment sur un gros forum pour l'un de mes projets. N'ayant rien trouvé dans les librairies gratuites et voulant un contrôle total sur le code et sur les vues, j'ai choisi de le coder moi-même.
C'est donc développé sous Cake PHP, et tout fonctionne bien. Cependant j'en arrive aux finitions : la partie post / edit / quote, qui est une question de temps, et la partie read / unread.
Cette dernière me poste quelques soucis : compte tenu de la structure complexe du forum et du nombre d'utilisateurs qu'il va recevoir (la base d'utilisateur potentielle du site étant de 5M d'utilisateurs), j'essaie de trouver un algo qui soit optimisée au mieux :
- le moins de vérifications possibles
- le moins de requête possibles
- le moins de données stockées possibles
A noter que je souhaite stocker ces liaisons en BDD pour plusieurs raisons :
- l'appli sera multi-device : site web, app mobile, app tablette, etc
- en terme UX, je ne supporte pas d'arriver sur un forum où toutes les catégories et tous les topics sont marquées comme non-lus quand je reviens, alors qu'une bonne partie n'a pas évolué depuis ma dernière visite, donc pas de session
- compter sur le client (cookie, local storage, etc) devient vite capricieux si un utilisateur possède plusieurs devices ou si plusieurs utilisateurs utilisent le device
La structure du forum est la suivante :
- Forum hasMany ForumsCategories
- ForumsCategories belongsTo Forum & hasMany Topics & hasMany Replies
- Topics belongsTo ForumsCateogy & belongsTo User & hasMany Replies
- Replies belongsTo ForumsCategory & belongsTo Topic & belongsTo User
La première idée qui me vient, c'est de faire des tables de liaisons :
- ForumsCategories_readBy_Users
- Topics_readBy_Users
- Replies_readBy_Users
Dans les faits je me dis tout d'abord que les Replies, ça va surcharger complètement le système. Donc ça, c'est à éviter.
Pour les Topics, ça devient un peu plus clair : l'utilisateur lit le topic, on passe la liaison à read.
Cependant, il y a plusieurs interrogations quant au passage à read :
- dois-je le faire uniquement sur la dernière page de réponses (on exécute un appel à setRead() uniquement si on est sur la dernière page de réponses du topic), voire sur la dernière réponse (en se basant sur l'ID de la réponse, qui est présent dans mon DOM HTML, et en faisant un appel en Ajax quand on attend l'ID en question)
- ou dois-je le faire sur chaque page du topic, ce qui simplifie l'exécution du code, mais peut nuire à l'expérience utilisateur (il n'a pas lu la fin du topic, mais celui-ci est considéré comme lu)
- et plus profond, dans le cas où des réponses sont postées s'il est sur le topic ? J'ai pensé à un long polling ou à une requête cyclique en ajax qui recharge les réponses et la pagination si de nouvelles réponses sont détectées, et à ce moment là on repousse le moment où le topic est marqué comme read. Mais ça fait beaucoup plus de requêtes
Pour les ForumsCategories, c'est un peu plus facile : si tous les topics sont read, alors la ForumsCategory est read également.
Mais les questions se posent alors sur la façon de faire :
- soit on inclus à chaque post de réponse un appel pour marquer la ForumsCategory en question comme unread ce qui peut faire beaucoup d'UPDATE dans la base
- soit on récupère à chaque affichage du listing ForumsCategories la table de liaison Topics_readBy_Users en tapant sur les topics appartenant à la ForumsCategory en question et le UserId de l'utilisateur connecté
L'une comme l'autre des solutions génèrent forcément beaucoup de requêtes. J'ai tendance à penser qu'en général, un traitement beforeSave est préférable à un traitement beforeFilter, les SELECT étant souvent plus nombreux et nécessitant moins de ressources que les INSERT ou UPDATE, mais en l’occurrence, je risque d'avoir énormément de réponses postées, alors que je pourrais ne générer de requête qu'à l'affichage de la vue par l'utilisateur.
N'ayant que peu de retour d'expérience là dessus (j'ai un peu fouillé PunBB et PHPBB il y a quelques années de cela, mais rien de plus), j'ai tendance à pensé qu'il n'existe pas vraiment de bonnes pratiques en la matière, c'est pourquoi je me tourne vers vous avant de me lancer dans une architecture complexe qui pourrait s'avérer bien trop gourmande.
Merci d'avance pour vos réactions et commentaires constructifs.