Coulisses techniques
Outils de monitoring : comment uh!ive supervise son infrastructure
Nous allons évoquer ici les outils de monitoring utilisés par uh!ive dans le cadre de la supervision de ses services. Les outils de monitoring…
23 juillet 2026
Coulisses techniques
Voici une petite anecdote sur la manière dont j’aborde l’enseignement de certains concepts à autrui.
Récemment, j’ai dû introduire quelques concepts d’Elm à un collègue qui avait une certaine expérience avec React et Redux. L’un de ces concepts était List.foldl, une fonction de réduction qui existe dans de nombreux langages, et qui correspond à Array#reduce en JavaScript.
Le collègue avait du mal à comprendre le concept dans son ensemble, alors j’ai tenté d’utiliser une métaphore ; j’ai pensé à une grande roue à côté d’un lac, avec quelqu’un dans l’un de ses paniers tenant un seau, remplissant le panier d’eau du lac chaque fois que le panier revient au sol.
Ouais, je sais.
Alors qu’il me regardait comme si j’étais un fou, et sachant qu’il avait déjà utilisé React et Redux, je lui ai dit que c’était comme les fonctions réductrices qu’il avait probablement déjà utilisées.
Nous avons commencé à écrire un réducteur Redux standard en JavaScript pur :
function reducer(state, action) {
switch(action.type) {
case "EMPTY": {
return init
}
case "ADD_WATER": {
return {...state, water: state.water + 1}
}
}
}
Il a fait « ah oui, je connais ça ». Bien ! Nous pourrions utiliser cette fonction de manière itérative :
// Construction de l'état étape par étape
const init = {water: 0}
let state = init
state = reducer(state, {type: "ADD_WATER"})
state = reducer(state, {type: "EMPTY"})
state = reducer(state, {type: "ADD_WATER"})
state = reducer(state, {type: "ADD_WATER"})
console.log(state) // {water: 2}
Ou en utilisant Array#reduce :
// Utilisation d'Array#reduce et d'un tableau d'actions
const actions = [
{type: "ADD_WATER"},
{type: "EMPTY"},
{type: "ADD_WATER"},
{type: "ADD_WATER"},
]
const init = {water: 0}
const state = actions.reduce(reducer, init)
console.log(state) // {water: 2}
Ainsi, je pourrais réutiliser la métaphore de la grande roue :
state représente l’état du panier de la roue (et la quantité d’eau qu’il contient)init est l’état initial du panier de la roue (il ne contient pas encore d’eau)actions sont la liste des opérations à effectuer chaque fois que le panier atteint le sol à nouveau (ici, remplir le panier avec de l’eau du lac, parfois vider le panier)Pour information, oui, mon collègue me regardait toujours bizarrement.
Nous avons continué et décidé de réimplémenter la même chose en Elm, en utilisant foldl. Sa signature de type est :
foldl : (a -> b -> b) -> b -> List a -> b
Wow, cela semble compliqué, surtout quand on débute en Elm.
En Elm, les signatures de type séparent chaque argument de fonction et la valeur de retour par une flèche (->) ; donc, décomposons celle de foldl :
(a -> b -> b), le premier argument, signifie que nous voulons une fonction, prenant deux arguments typés a et b et retournant un b. Cela ressemble beaucoup à notre fonction reducer en JavaScript ! Si c’est le cas, a est une action et b un état.b, est l’état initial à partir duquel nous commençons à réduire notre liste d’actions.List a, est notre liste d’actions.b, donc un nouvel état. Nous avons la définition exacte de ce que nous recherchons.En fait, notre propre utilisation de foldl aurait été beaucoup plus évidente si nous avions vu cela initialement, en remplaçant a par Action et b par State :
foldl : (Action -> State -> State) -> State -> List Action -> State
Note : si tu as encore du mal avec ces a
et b, tu devrais probablement lire un peu sur les Types Génériques.
Notre implémentation minimaliste résultante était :
type Action
= AddWater
| Empty
type alias State =
{ water : Int }
init : State
init =
{ water = 0 }
actions : List Action
actions =
[ AddWater
, Empty
, AddWater
, AddWater
]
reducer : Action -> State -> State
reducer action state =
case action of
Empty ->
init
AddWater ->
{ state | water = state.water + 1 }
main =
div []
[ -- Construction de l'état étape par étape, affiche { water = 2 }
init
|> reducer AddWater
|> reducer Empty
|> reducer AddWater
|> reducer AddWater
|> toString >> text
-- Utilisation de List.foldl, affiche { water = 2 }
, List.foldl reducer init actions
|> toString >> text
]
Nous avons rapidement ébauché cela sur Ellie. Ce n’est pas graphiquement impressionnant, mais ça fonctionne.
C’était ça, c’était plus évident de cartographier les choses que mon collègue connaissait déjà sur quelque chose de nouveau pour lui, alors qu’en fait, c’était exactement la même chose, exprimée légèrement différemment d’un point de vue syntaxique.
Nous avons également expliqué que l’Architecture Elm et la fonction traditionnelle update étaient essentiellement une projection de foldl, Action étant habituellement nommé Msg et State Model.
Le truc amusant, c’est que le design de Redux a lui-même été initialement inspiré par l’Architecture Elm !
En conclusion, voici quelques points à retenir lorsque tu fais face à quelque chose de difficile à comprendre :
Coulisses techniques
Nous allons évoquer ici les outils de monitoring utilisés par uh!ive dans le cadre de la supervision de ses services. Les outils de monitoring…
23 juillet 2026
Coulisses techniquesProduit
uh!ive fournit une suite complète de services pour traiter et analyser la voix (speech analytics, speech-to-text), ainsi qu'une application web pour accéder à…
5 mai 2026