Coin web de Frédéric Péters

Stamina, à l’antenne

RĂ©sumĂ© des Ă©pisodes prĂ©cĂ©dents : il y a quinze ans (…) la radio a adoptĂ© un système de diffusion automatique, on y a fait quelques patchs, il n’a plus Ă©tĂ© dĂ©veloppĂ©, on a continuĂ© Ă  l’utiliser, j’ai parfois eu envie de le remplacer, ça n’a jamais abouti (sauf Ă  un nom, stamina); pendant toutes ces annĂ©es le site web a Ă©tĂ© refait, avec une partie gestion qui a petit Ă  petit gagnĂ© une vue sur la diffusion (pour par exemple afficher sur le site l’émission ou le morceau en cours), et puis 2020 tout Ă©tait lĂ  ou presque, on Ă©tait en mai, j’ai repris l’idĂ©e de faire la diffusion et posĂ© quelques lignes de code, c’était Stamina, nouveau retour.

Depuis il s’est passé des choses, récit.

J’ai continué sur la lancée et mi-juin j’ai déployé le tout en vrai mais pas tout de suite à la radio, juste chez moi, sur le vieux netbook de la chaine hi-fi, où du coup j’ai programmé des tranches musicales aléatoires avec « ma » musique, avec des jingles de test, en y définissant aussi des émissions « stream » pour basculer à heures fixes des fichiers locaux au stream de la radio, idéal pour ne plus rater le début de nos diffusions de radio vedette le vendredi à 15h (vive le Poitou).

Ainsi donc j’ai tourné avec ma propre sélection, ajouté des bugs et corrigé du code, pour arriver début juillet et réouverture des piscines oblige préparer le grand saut. Métaphore filée petit bassin d’abord, quelques heures semaine dernière, en tranche musicale, tout se passe bien, ça me permet de noter quelques points à ajuster (principalement on a une info sur la page d’accueil de l’écran en régie, avec le morceau en cours de diffusion et la prochaine émission programmée, et ça passe par un petit script CGI qui interrogeait l’ancien système).

Mais dimanche matin, je lance le système pour de bon, ça tourne et arrive la première Ă©mission programmĂ©e et jingle, jingle, jingle, oups, stop, restart de l’ancien système, debug et idiot j’avais oubliĂ© d’exporter les fichiers vers le serveur. J’ajoute le partage NFS, j’en profite pour faire ça moderne et via une mount unit systemd (mnt-panikdb_media.mount) :

[Unit]
Description=Panikdb /media/
Wants=network-online.target

[Mount]
What=panikdb.panik:/srv/panikdb/panikdb/media/
Where=/mnt/panikdb_media
Type=nfs
Options=nfsvers=4,tcp,rsize=32768,wsize=32768,ro,async,soft,intr,nolock

(sans réfléchir vraiment aux options, en recopiant ce que j’utilise ailleurs).

Je profite aussi de ce temps pour créer l’unit pour le service stamina,

[Unit]
Description=Stamina
After=network.target jack-plumbing.service mnt-panikdb_media.mount

[Service]
Environment=LANG=C.UTF-8
Environment=PANIKDB_SETTINGS_FILE=/etc/panikdb/settings.py
Environment=PYTHONUNBUFFERED=1
User=panik
Group=panik
ExecStart=/usr/bin/panikdb-manage stamina
KillSignal=SIGQUIT
TimeoutStartSec=0
PrivateTmp=true
Restart=always
Type=exec
StandardError=syslog

[Install]
WantedBy=multi-user.target

Avec sans doute le network.target qui est redondant, et le seul truc Ă  noter peut-ĂŞtre l’arrivĂ©e un peu plus tard de PYTHONUNBUFFERED=1; la petite histoire Ă©tant que le logging se faisait via des print(), qu’au dĂ©but j’ai Ă©tĂ© surpris de ne rien voir dans la sortie de journalctl, que j’ai dirigĂ© ces print() vers sys.stderr, qu’évidemment ça allait mieux sauf qu’à un moment arrive dans les logs :

jui 13 21:41:22 soma panikdb-manage[7033]: 2020-07-13 21:30:00.678248 unexpected
 … change Acouphène vs Diffusion of 82.2 feat Teratoma at 21:30

et bizarre cette différence entre le 21h41 de journalctl et le 21h30 de la ligne de log produite. Bizarrerie qui me fait réécouter la pige d’antenne et constater que ça a bien déclenché à 21h30 et de là me dire que ça venait sans doute malgré tout du buffering (sur stderr ?) et qu’il était utile d’ajouter cette variable à l’environnement.

Petite histoire qui ne se terminera pas là parce que quand même je finirai par me convaincre que les print() c’est quand même un peu la lose et je les remplacerai par une utilisation du module logging, fait pour ça (mais dont je ne suis toujours pas fan).

Voilà donc la diffusion qui tourne toute la nuit et le matin et la journée et tout va bien et pas de plot twist sur un effondrement final. Restent les bonus :

Bonus 1, pour dĂ©ployer une nouvelle version, il y a juste le code/paquet Ă  mettre Ă  jour (c’était en partie l’objet du post prĂ©cĂ©dent) puis il y a un mini-serveur qui tourne et permet de demander un arrĂŞt dans la douceur, c’est-Ă -dire d’attendre la fin du morceau, ce qui permet de faire :

panik@soma:~$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Watusi!
Known commands: status, softquit, hardquit
(dot on empty line to stop connection)
softquit
{"ack": true}
Connection closed by foreign host.

et comme il y a Restart=Always dans la définition du service, ça redémarrera tout seul.

On aura noté ce protocole hybride avec des bouts de JSON, c’est ainsi parce que pas envie d’intégrer une dépendance sur aiohttp et c’est tellement simple à gérer avec asyncio que voilà.

Bonus 2, pour fĂŞter cette mise en place, assez invisible autrement, un nouveau tableau de bord pour voir en un coup d’œil ce qui est programmĂ© Ă  venir, ça ressemble Ă  ça :

Capture d’écran panikdb

En conclusion temporaire, c’est là qu’on est et c’est loin d’être terminé. J’ai commencé à accumuler les évolutions qui sont désormais possibles et une des premières va concerner la sélection des morceaux diffusés, aujourd’hui aléatoire excluant les morceaux passés récemment, on voudra pouvoir dire que dans telle tranche horaire on veut par exemple un certain quota de titres en français, et biaiser la sélection pour atteindre celui-ci.

15 juillet 2020, 11:23