betagouv / rdv-service-public

Prise de RDV pour les services publics
https://rdv.anct.gouv.fr
GNU Affero General Public License v3.0
14 stars 2 forks source link

Performance du calcul des créneaux de disponibilités #2939

Open DanteZ5 opened 1 year ago

DanteZ5 commented 1 year ago

Actuellement

Objectif

Technique

1ère hypothèse d'amélioration : stocker en base des objets de disponibilités (par exemple : Disponibilite)

2nde hypothèse (moins structurante) : isoler le calcul du prochain créneau

3ème hypothèse (écartée ou optionnelle) : mettre en cache le calcul

francois-ferrandis commented 1 year ago

C'est une belle analyse que tu proposes ici ! Les conclusions de ma dernière investigation étaient :

Bien sûr, des optimisations de l'algo sont possibles, mais il y a des contournements qui sont potentiellement plus efficace que de complexifier notre code pour les perfs. ;)

DanteZ5 commented 1 year ago

échanges avec @damienlethiec : une approche "en douceur" serait de commencer par l'hypothèse 2 : isoler le calcul du prochain créneau ça répondrait à un besoin direct sur certains temps de chargement + un endpoint d'API, même si ça ne répond pas à l'ensemble du besoin. PR réalisable à partir de cette hypothèse

damienlethiec commented 1 year ago

J’ai regardé de mon côté également les possibilités en terme d’amélioration de la perf de la recherche de créneaux. Et j’ai eu l’impression d’ouvrir la boîte de pandore. La situation tech actuelle rend ce calcul vraiment très compliqué. Et même améliorer la perf du calcul du prochain créneau ne serait pas trivial. J’ai donc vite refermé la boîte de pandore. Pour ne pas que cette exploration, même rapide, ne serve à rien, j’aimerais laisser 2 traces:

Tout d’abord, pour faciliter sa compréhension, je veux documenter ici en pseudocode le fonctionnement du service SlotBuilder, que j’ai n’ai pas trouvé si facile à prendre en main. N’hésitez pas à vérifier que je n’écris pas de bétises. Est-ce que ça aurait de la valeur d’intégrer ce pseudo code dans le code ? Ce service a pour but de déterminer les créneaux de rendez-vous disponibles pour un motif et un lieu donné, une liste d’agents donnée et une plage temporelle donnée et à l’exclusion de jours fériés. Son fonctionnement est le suivant:

  1. Convertir le range de dates passé en argument en range de datetimes.
  2. Déterminer les plages d’ouvertures existantes dans cette range (récurrentes y compris)
  3. Convertir chacune de ces plages d’ouverture en range de datetime compatibles avec le range passé en arguments
  4. Soustraire à ces ranges les temps occupés par des absences, des jours off ou des rdv déjà pris. A cette étape, on a hash qui associe pour chaque plage d’ouverture un array de ranges
  5. Itérer sur l’array de range de chaque plage d’ouverture. Pour chaque range, construire les créneaux accessibles grâce à la durée du motif de rendez-vous. Regrouper tous ces créneaux dans un array et le retourner.

De son côté, la recherche du prochain créneau appelle le SlotBuilder semaine par semaine à partir de la date d’aujourd’hui jusqu’à trouver un créneau ouvert (ou s’arrête au bout de 6 mois)

Ensuite, les options envisagées si on veut vraiment améliorer les perfs (de la plus envisageable à la plus folle):

Voilà, quelques pistes. Sans doute pas grand chose à en faire pour l’instant mais au moins on garde une trace de ces réflexions.

yaf commented 1 year ago

J'ajoute ma petite graine.

Je traine l'hypothèse 1 depuis un moment. Nous allons en avoir besoin pour #2515 de toute façon. Cela va permettre de repartir la première partie du calcul (la moitié peut-être ?) sur l'écriture d'objet temporel (indispo, plage d'ouverture, RDV).

Et peut-être qu'il faut faire ça (le ticket #2515 arrive en haut de nos priorités en ce moment sur le médicosocial) avant d'attaquer la construction d'un calcul séparé pour trouver le premier créneau dispo.

damienlethiec commented 1 year ago

J'ai clôturé #2984

Après discussion avec Victor, quelques billes:

Gains de perf créneaux via pagination à reprendre et documenter (cache nécessaire et complexe sauf si faible temps de remise à jour et pas sûr de l’utilisation produit des gens (utilisation pagination ou pas et problème avec cache pas à jour ou pas))