Singleton, chargement de multiples applications Flex (SWF) et loaderContext
98% du temps, je vous dirais que la création de Singletons dans votre application est une mauvaise pratique, à éviter (par expérience). Bon, il reste 2%, tout premièrement car le framework Flex utilise lui-même des Singletons (chaque application est un singleton, mais aussi PopUpManager, DragManager, CursorManager & co). Et parfois, ils peuvent vous sauver la mise pour éviter de mettre en branle des techniques de sioux pour arriver à ses fins.
C'est ce qui m'est arrivé hier pendant mes développements dans une situation assez spéciale que l'on ne rencontre pas tous les jours.
Le contexte.
Je développe actuellement une administration pour un SIG Web qui consiste en une série d'applications Flex. Ces applications sont indépendantes dans leur fonctionnement et sont chargées par une application-mère qui consiste simplement en un TabNavigator contenant des SWFLoader.
Un petit schéma pour expliquer la situation:
La contrainte
Ces applications communiquent toutes avec un seul et même serveur baptisé Aigle. Ce serveur ne peut, par utilisateur, ne recevoir qu'une seule requête à la fois et c'est ici la contrainte qui nous intéresse. Si le serveur reçoit 2 requêtes du même utilisateur, la 2 sera mise en attente pendant un certain temps. Si la sous-application 1 fait une requête assez longue et que l'on bascule sur un autre onglet pour faire quelque chose qui va envoyer un autre requête, on tombera donc sur ce problème.
Le système d'envoi de requêtes en 2 mots
Pour envoyer des requêtes au serveur, j'utilise un Singleton (oui, c'est le dernier) nommé "RequestManager". Celui-ci s'occupe d'envoyer les requêtes au serveur à la chaine. Quand on tente d'envoyer une requête, on va simplement alimenter une pile de requête qui se dépile lorsque l'on reçoit le retour d'une requête. On a donc une FIFO (si je ne m'abuse) qui me permet de ne pas me heurter à la contrainte imposée par le serveur.
La classe RequestManager se trouve dans une librairie, utilisée par tous les projets.
Première approche, chargement simple des SWF applicatifs avec SWFLoader
Dans un premier temps, j'ai tenté de simplement créer des new SWFLoader et de faire un load(pluginPath.swf). Dans ce cas-là, chaque SWF est dans une "sandbox" locale. Il n'y a aucun partage de classe, chaque SWF est une entité bien distincte. Si on charge 6 sous-applications, on aura donc 6 instances bien distinctes de RequestManager (ce sont des Singletons par rapport à chaque SWF).






