Atelier du 16/11/2019

La semaine dernière : Atelier du 9 nov. 2019

Cette seconde 1/2 journée nous a permis de commencer la mise en œuvre de « tubes nommés ».

Exemple

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import io
import json

class Pipes:
    'Définit et met en oeuvre la communication au travers de tubes nommés'

    def __init__(self, path):
        self._mainPath = path
        
    def __enter__(self):
        self._createPipe(self._mainPath)
        self._fifo = io.open(self._mainPath, "rb", buffering=0)
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        self._fifo.close()
        self._deletePipe(self._mainPath)
        
    def getMainPath(self):
        return self._mainPath

    def _createPipe(self, path):
        try:
            os.mkfifo(path)
            print("Tube créé (" + path + ").")
        except FileExistsError:
            print("Tube déjà existant (" + path + ").")

    def _deletePipe(self, path):
        os.remove(path)
        print("Tube supprimé (" + path +")")
        
    def sendMessage(self, message):
        with open(self.__mainPath, "w") as fifo:
            fifo.write(message)
        fifo.close()

    def readMessage(self):
        s = bytearray()
        while self._fifo.readable():
            try:
                s.append(self._fifo.read(1)[0])
            except IndexError:    # read vide !
                return None
                break
            
#            print(s)
            try:
                dec = json.loads(s)
                return dec
                break
            except json.JSONDecodeError as e:
#                    print(e)
                pass
            
#        return dec
        
if __name__ == "__main__":
    modules = []
    with Pipes() as pipes:
        while True:
            r = pipes.readMessage()
            if r:
                try:
                    e = r['hello']
                    pipes._createPipe('/tmp/' + e)
                    modules.add('/tmp/' + e);
                except KeyError:
                    print("Je n'ai pas trouvé hello, message ignoré !")
                    continue
                
                print(e)
                
            else:
                break

Le but de ce code est de montrer comment on va pouvoir communiquer (lire en particulier) des messages en utilisant les tubes nommées.

Le fichier est constitué de 4 zones :

  • L’entête qui comporte 2 lignes importantes, le première indiquant l’adresse de l’interpréteur, la seconde indiquant l’encodage du fichier (UTF-8) ;
  • La zone des imports qui indique quels modules doivent être chargés ;
  • La définition de la classe « Pipes » ;
  • Enfin, le programme.

La classe

Elle est chargée pour chacune de ses instance de mettre en œuvre un tube nommé et permettre la lecture de messages dans ce tube.

Elle définit plusieurs méthodes “magiques”, le constructeur __init__, deux méthodes nécessaires à l’utilisation du mot-clé with (__enter__ et __exit__), deux méthodes privées (précédées d’un tiret-bas) et deux méthodes publiques.

L’utilisation de cette classe avec le mot-clé with permet de créer un contexte et d’assurer certains traitements à l’entrée et à la sortie du bloc quelque soient les conditions (exceptions par ex.), cf. : https://docs.python.org/fr/3/reference/compound_stmts.html#with.

L’intérêt ici est de s’assurer de la création des tubes nommés, mais surtout de leur suppression en fin de bloc.

C’est aussi l’occasion de déplacer le code dans un repository GitHub et de le rendre public :

https://github.com/Marcussacapuces91/robot-roulant