• [^] # Re: Go ou Rust côté backend, système ou embarqué

    Posté par (site web personnel) . En réponse au journal La ronde (boucle?) des langages. Évalué à 10.

    Avec go, si on utilise que les channels pour communiquer entre goroutine et pas de lock, il n'y a pas de problème potentiel.

    Je suis un développeur confirmé en Go et cette affirmation est fausse. Je passe sur les questions de deadlock ou de fuite de goroutines (ce sont des problèmes potentiels, mais disons que c'est en dehors du cadre du thread safety). Par contre, la communication entre goroutine par un channel ne garantit pas l'absence qu'une écriture dans une goroutine puisse avoir des effets dans une autre goroutine (j'en ai fait plusieurs fois la douloureuse expérience).

    Quand on envoie une valeur d'une goroutine à une autre goroutine dans un channel, ça en fait une copie par valeur. Ça veut dire que si on envoie un type simple (un entier ou une chaîne de caractères), on est tranquille, ce qu'on modifie d'un côté n'a pas d'effets de l'autre. Par contre, si on commence à passer des choses plus compliquées, par exemple une struct avec un pointeur vers une autre struct (mais c'est aussi vrai pour les maps ou les slices), les deux goroutines vont avoir une struct (pas la même en mémoire) avec un champ qui pointe sur la même struct. Et, du coup, on se retrouve avec la problématique des accès concurrents à cette struct.

    Une solution pour s'en sortir est de faire du deep clone avant d'envoyer sa structure dans le channel. Malheureusement, en Go, ce n'est pas facile à faire (à cause de l'absence de génériques et parce que la réflexion n'a pas accès aux champs privés). On peut faire ça en sérialisant puis désérialisant vers du JSON, mais c'est lent et on perd les champs privés. Et c'est comme ça que pour Cozy Cloud, on s'est retrouvé avec des méthodes Clone à un paquet d'endroits que l'on maintient à la main, avec de temps en temps des erreurs ou oublis.