Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tech - Correction de la fuite mémoire avec le state vessels #3742

Merged
merged 13 commits into from
Oct 9, 2024

Conversation

louptheron
Copy link
Collaborator

@louptheron louptheron commented Oct 4, 2024

Linked issues

Filtres

  • Création de features/Filter
  • Sauvegarde des filtres avec persistReducerTyped et non plus en direct avec le localstorage

Navires

  • Création de features/Vessel
  • Ajout d'un createEntityAdapter pour les dernières positions des navires (vessels)
  • Normalisation des navires vessels : suppression du sous-objet vesselProperties
  • Ajout de use-cases redux-thunk pour intégagir avec la layer VesselsLayer d'OL
  • Utilisation de vesselsAdapter.setMany pour éviter les fuites mémoires
  • Sortie de VESSELS_VECTOR_SOURCE et VESSELS_VECTOR_LAYER dans une constante, en dehors d'un composant React
  • Utilise featuer.get au lieu de feature.getProperties pour éviter un shallow copy des propriétés

Liste des navires

  • Ajout d'une condition sur VesselList pour ne pas écouter vessels dès le démarrage de l'app
  • Migration des useState locaux dans le slice

  • Tests E2E (Cypress)

@louptheron louptheron marked this pull request as ready for review October 8, 2024 12:57
@louptheron louptheron force-pushed the loup/fix_memory_leak_on_vessels branch from aebd5a4 to 93de412 Compare October 8, 2024 12:57
Copy link
Contributor

@ivangabriele ivangabriele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done :) Y a plein de comments mais presque tous sont des questions de refacto / goûts.

J'ai vu plein d'import COLORS qui viennent encore de constants, j'ai arrêté les comments liés à ça du coup. Si tu as la motiv tu peux les retirer, sinon c'est pas grave ça sera fait un jour !

['vesselProperties', 'mmsi'],
['vesselProperties', 'ircs']
],
keys: [['vesselName'], ['internalReferenceNumber'], ['externalReferenceNumber'], ['mmsi'], ['ircs']],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On garde les arrays dans l'array ?


import type { MainAppThunk } from '@store'

export const renderVessels = (): MainAppThunk => async (_, getState) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const renderVessels = (): MainAppThunk => async (_, getState) => {
export const renderVesselFeatures = (): MainAppThunk => (_, getState) => {

?

@@ -15,7 +15,7 @@ export const showAlertInSideWindow =
flagState: selectedVessel.flagState,
internalReferenceNumber: selectedVessel.internalReferenceNumber,
ircs: selectedVessel.ircs,
name: selectedVessel?.alerts[0] ?? null
name: selectedVessel?.alerts?.length ? selectedVessel?.alerts[0] : null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: selectedVessel?.alerts?.length ? selectedVessel?.alerts[0] : null
name: selectedVessel.alerts?.length ? selectedVessel?.alerts[0] : null

// @ts-ignore
const extent = getExtentFromGeoJSON(zonesSelected[0]?.feature)
if (extent?.length && !isNumeric(extent[0]) && !isNumeric(extent[1])) {
dispatch(setProcessingRegulationSearchedZoneExtent(extent))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je sais que ce n'est pas créé sur cette PR mais le nommer setSelectedRegulationZoneExtent() ne serait pas plus clair ?

const extent = getExtentFromGeoJSON(zonesSelected[0]?.feature)
if (extent?.length && !isNumeric(extent[0]) && !isNumeric(extent[1])) {
dispatch(setProcessingRegulationSearchedZoneExtent(extent))
dispatch(animateToExtent())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Peut-être en TODO mineure pour plus tard mais je trouve ça plus clair quand une action UI est "auto-contenue". Du genre (en pseudo-code) setExtent(nextExtent: [...], withAnimation: true) plutôt que de setter d'abord une valeur pour ensuite déclencher l'animation via une autre action qui utilise cette valeur.

const filters = useMainAppSelector(state => state.filter.filters)
const rightMapBoxOpened = useMainAppSelector(state => state.global.rightMapBoxOpened)

const isOpen = useMemo(() => rightMapBoxOpened === MapBox.FILTERS, [rightMapBoxOpened])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const isOpen = useMemo(() => rightMapBoxOpened === MapBox.FILTERS, [rightMapBoxOpened])
const isOpen = rightMapBoxOpened === MapBox.FILTERS

?

@@ -81,18 +71,18 @@ const VesselAlertLayer = () => {
const { vesselIsHidden, vesselIsOpacityReduced } = getVesselLastPositionVisibilityDates(vesselsLastPositionVisibility)

const features = vessels.reduce((features, vessel) => {
if (!vessel.vesselProperties.hasAlert) return features
if (!vessel.hasAlert) return features
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Un switch(true) serait plus clean à mon goût mais c'est tout à fait personnel.

+ Même remarque pour les autres layers.

Comment on lines +23 to +30
const hideNonSelectedVessels = useSelector(state => state.vessel.hideNonSelectedVessels)
const vesselsTracksShowed = useSelector(state => state.vessel.vesselsTracksShowed)
const selectedVesselIdentity = useSelector(state => state.vessel.selectedVesselIdentity)
const vessels = useSelector(state => vesselSelectors.selectAll(state.vessel.vessels))
const nonFilteredVesselsAreHidden = useSelector(state => state.filter.nonFilteredVesselsAreHidden)
const previewFilteredVesselsMode = useSelector(state => state.global.previewFilteredVesselsMode)
const hideVesselsAtPort = useSelector(state => state.map.hideVesselsAtPort)
const vesselsLastPositionVisibility = useSelector(state => state.map.vesselsLastPositionVisibility)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const hideNonSelectedVessels = useSelector(state => state.vessel.hideNonSelectedVessels)
const vesselsTracksShowed = useSelector(state => state.vessel.vesselsTracksShowed)
const selectedVesselIdentity = useSelector(state => state.vessel.selectedVesselIdentity)
const vessels = useSelector(state => vesselSelectors.selectAll(state.vessel.vessels))
const nonFilteredVesselsAreHidden = useSelector(state => state.filter.nonFilteredVesselsAreHidden)
const previewFilteredVesselsMode = useSelector(state => state.global.previewFilteredVesselsMode)
const hideVesselsAtPort = useSelector(state => state.map.hideVesselsAtPort)
const vesselsLastPositionVisibility = useSelector(state => state.map.vesselsLastPositionVisibility)
const {
hideNonSelectedVessels,
vesselsTracksShowed,
// ...
} = useMainAppSelector(state => ({
hideNonSelectedVessels: state.vessel.hideNonSelectedVessels,
vesselsTracksShowed: state.vessel.vesselsTracksShowed,
// ...
}))

+ Même remarque pour les autres layers.

} from '../../../domain/entities/vessel/vessel'
import { useIsSuperUser } from '../../../auth/hooks/useIsSuperUser'
import { monitorfishMap } from '../../map/monitorfishMap'
import { vesselsAdapter, vesselSelectors } from '../slice'

const VesselAlertLayer = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposition de TODO : j'en ferais plutôt un hook en memoizant simplement les features plutût qu'un composant memoizé sans rendu.

+ Même remarque pour les autres layers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Autre PR please ^^

@@ -228,18 +233,39 @@ export function VesselsLabelsLayer({ mapMovingAndZoomEvent }) {
}

const nextFeaturesAndLabels = features.map(feature => {
const { vesselProperties } = feature
const vesselProperties = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne sais pas si c'est utilisé à plus de deux endroits mais je me pose la question d'un petit util selon ^^.

Copy link

sonarqubecloud bot commented Oct 9, 2024

@louptheron louptheron merged commit 79ef835 into master Oct 9, 2024
26 checks passed
@louptheron louptheron deleted the loup/fix_memory_leak_on_vessels branch October 9, 2024 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Intégrer les changements de l'audit de perf
2 participants