L'application devra pouvoir s'éxécuter sur au moins 3 plates-formes :
Le choix de la plate-forme Linux arm64 peut sembler déroutant. En fait, la plupart des boîtiers de connexion à l'Internet (box) qui offrent la capacité d'exécuter une machine virtuelle en leur sein, s'exécutent sur plates-formes arm64. Or, pour un particulier, quitte à consommer de l'électricité, autant exécuter l'application sur sa box. Cela évite d'avoir une machine supplémentaire ou de louer un VPS pour le faire.
En raison de cet aspect multi plates-formes et pour avoir des performances optimum, les développements se feront avec l'infrastructure Qt 6.11 et l'IDE qtcreator.
La réalisation d'un système à plusieurs étages est souvent difficile à mettre au point. Nous avons décidé d'encapsuler chaque bloc fonctionnel dans une interface disposant d'entrées et de sorties. Cette interface est dérivée par un ensemble de classes concrètes qui la mettent en oeuvre. Un prototype (application) permettra de tester chacune d'elle, c'est à dire chaque bloc fonctionnel en simulant les entrées attendues.
La définition des interfaces principales découle de l'analyse en blocs fonctionnels :
Dès qu'un bloc fonctionnel est jugé stable, il est intégré à l'application principale où il sera de nouveau testé (tests d'intégration).
Pour le bon fonctionnement des tests, les modules fonctionnels doivent être réalisés dans un ordre précis. Le schéma montrant l'organisation générale des traitements permet dde préciser cet ordre afin de pouvoir effectuer les test dans le bon ordre :
FilesQueue intégrée à la librairie
jmp) ;
Archiver).
Ce dernier est particulier en ce sens qu'étant central, il se développe au fur et à mesure du développement
des autres blocs fonctionnels ;
EmlReader) ;
EmlScanner) ;
EmlComposer) ;
EmlDispatcher) ;
EmlSender) ;
L'appel direct de méthodes d'objets s'exécutant sur des threads différents pouvant accéder à de même ressources est sourcede bugs subtils et difficiles à reproduire. Pour les éviter, nous nous appuierons sur le mécanisme signal/slots de la plate-forme Qt pour assurer les communications inter-threads (lignes rouges).
Notez que l'ordre de développement n'est pas celui d'instantiation des objets accompagnée de la modification de leur thread d'affinité. L'odre de lancement est le suivant :
t_redirected)
il peut aussitôt les rémettre ;
Les besoin de configuration sont à décrire dans les spécifications de chaque bloc fonctionnel tandis qu'un chapître synthétise le besoin de configuration.
Dans les spécification tehniques de chaque bloc fonctionnel, une section sera réservé aux échanges signaux/slots. En effet, ce mécanisme "casse" la logique séquentielle d'une routine. En mode multithreads, les connexions sont dites queued. Cela signifie que les signaux sont transformés en évènements et émis vers la boucle évènementielle de chaque thread qui exécute un slot connecté à ce signal. Ce sont donc des opérations asynchrones et on ne peut donc pas présumer du moment ou le slot est exécuter. Cela complique la vision globale du fonctionnement et rend plus difficle la mise au point. Il est donc important de maitriser ces échanges signaux/slots.
Nous avons identifié 2 ressources communes :
Pour l'instant nous traitons de 6 threads, mais il en existe un septième : le thread principal. Dans l'architecture proposée, ce dernier attend que sa boucle évènementielle reçoive l'odre d'arrêt pour mettre fin à l'application. Il ne fait donc pas grand chose.
Toutefois, nous avons besoin d'instancier des objets complexes donnant accès à des ressources partagées comme
le gestionnaire de connexions PostgreSQL.
C'est ce thread qui exécutera la réponse aux demandes de ressources commune.
Pour en faciliter l'accès, nous créons la classe singleton CommonResources qui
peut être invoquée par les constructeurs des objets construits sur le thread principal pour référencer une ou
plusieurs ressources partagées.
L'emploi de la ressource se fera, quant à elle, sur le thread du slot qui l'utilise.
Si la ressource est unique et ne supporte pas les accès concurrents, elle devra être protégée de ces derniers.
Dans le cas du gestionnaire de connexion PostgreSQL, cela n'est pas nécessaire car la connexion instanciée depuis
un slot n'est pas "vue" des slots s'exécutant dans un thread différent (rappel : nous utilisons la librairie
libpq et non l'objet de classe QDatabase).
Le journal assure déjà sa propre protection d'enregistrement des traces. Il n'y a donc pas lieu de renforcer sa protection au regard des accès concurrents.