Nous avions un service purement b2c (un webshop disons) avec ses propres particularités, mais uniquement orienté B2C.
Après plusieurs années, les difficultés de rentabiliser l'activité nous ont doucement orienté vers quelques efforts B2B, en utilisant une partie de nos capacités que nous avions développé en B2C.
Cela s'est fait relativement doucement et il y avait pas mal de liens (dans le modèle de données notamment) entre l'activité B2B et B2C (car utilisait les mêmes produits, une partie des même process, etc..) et avec dans les développements des parties uniquement lié au B2B.
A un moment, nous avons décidé de complètement pivoter et de stopper l'activité B2C.
De notre côté, pour éviter du code mort, de la maintenance inutile et avoir de bonnes nouvelles bases, nous avons "détaché" tous les éléments B2C que ce soit dans les modèles de données, les apis, les fronts, etc.. (en gros on a supprimé à ce moment là 50% de la base de code), on était content, une base propre, et de quoi continuer à développer notre activité B2B, ajouter des fonctionnalités etc..
... mais bien sûr (sinon je ne serais pas ici pour en parler) ... pas de multitenancy, nous avions gardé une bonne base du b2c qui n'en comportait pas. Certes dans notre modèle B2B, nous pouvions gérer des entreprises différentes, des sous companies, etc.. et nous pensions être tranquille avec ça.
Puis sont arrivé des entreprises qui nous ont demandé si on pouvait leur dédier notre soft et on s'est retrouvé un peu coincé :-)
La décision de comment gérer le multinenant a postériori est compliquée:
- une solution techniquement simple de dupliquer les infras n'est pas trop compliquée à mettre en oeuvre (mais augmente la maintenance) mais si ton front est une app mobile par exemple qui est dans les stores, tu n'as pas envie du tout de dupliquer tes apps mobiles pour chaque nouveau 'tenant', tu dois adapter ton app pour la faire se connecter à la bonne infra, ce qui peut dégrader ton UX, c'est bof
- une solution de garder le front, garder des apis uniques et multiplier les bases de données est possible, mais assez complexe techniquement aussi, notamment en devops, chez nous l'outil qui gére les versionning des schémas des bases de données (upgrade / downgrade) ne savait pas gérer nativement des multiples bases à upgrader / downgrader par exemple (mais cela peut avoir ses avantages d'utiliser cette solution pour des raisons de sharding et de véritable wall entre les tenants)
- une solution de gérer le multitenant nativement dans la base de donnée était ce qu'on préférait faire, mais c'est celle qui nécessitait le plus de travail évidemment et comportait aussi pas mal de risques de sécurité (garantir que les datas d'un tenant ne fuitent jamais dans un autre) qu'il faut combler par beaucoup de nouveaux tests units et E2E
Bref, a refaire, même en pur B2C, il faut évidemment gérer le multitenant dès le départ : si on le gère à la conception, cela ne rajoute que peu d'overhead dans les devts, même en incluant les tests de sécu supplémentaires (qu'on peut relativement automatiser)
"A life without a struggle on your part to make yourself EXCELLENT is hardly a life worth living."
Firefox avait beaucoup de fonctionnalités intéressantes. La navigation par onglets, des outils de débogage et des corrections de bugs réguliers. Chrome en avait également. Mais quand je l'ai vu démarrer presque instantanément au lieu des cinq secondes qu'il a fallu à Firefox, j'ai immédiatement basculé sur Google et je n'ai jamais regardé en arrière. Comme cela sera expliqué plus tard par les ingénieurs de Google, la vitesse était une priorité fondamentale.
Une fois que votre logiciel (ici Firefox) est lent, il est plus difficile, à postériori, de refactorer le code pour le rendre plus rapide.
Les développeurs de Firefox ont tenté de corriger le temps de démarrage de cinq secondes en 2010 via le bug #627591. Ils ont résolu de nombreux problèmes mais pas suffisamment pour justifier un deuxième essai de la part de beaucoup d'utilisateurs.
(source: There are called opportunies, de Fabien Sanglard)
A l'inverse, l'équipe derrière Google Chrome avait mis en place dès le début du projet un test automatisé dans le pipeline d'intégration continue (CI) pour s'assurer que les performances ne faiblissaient pas après chaque modification de code :
Nous surveillons attentivement les performances de démarrage à l'aide d'un test automatisé qui s'exécute pour presque chaque modification du code. Ce test a été créé très tôt dans le projet, lorsque Google Chrome n'a presque rien fait, et nous avons toujours suivi une règle très simple: ce test ne peut jamais être plus lent.
Parce qu'il est beaucoup plus facile de résoudre les problèmes de performances au fur et à mesure qu'ils sont créés que de les résoudre ultérieurement, nous sommes rapides pour corriger ou annuler les régressions. En conséquence, notre très grande application démarre aussi vite aujourd'hui que l'application très légère avec laquelle nous avons commencé.
(source: IO in Google Chrome)
La répétition fait le maitre. C'est tout aussi vrai en informatique (source de la vidéo).
Ne pas aller jusqu'au bout des choses sur un petit périmètre.
Et par là j'entends intégration continue (Continuous Integration), déploiement continu (Continuous Deployment), 100% de test automatique des tests-unitaires jusqu'au tests systèmes (end-to-end), documentation générée, changelogs, infrastructure as code, limites, quotas, pas de "single point of failure" (spof) — , architecture multi-tenant...
C'est de-facto être incapable de réaliser tout cela, dans les temps, sur un projet d'envergure.
Et vous, quelles sont vos retours d'expérience concernant l'application de ce principe ?