Question

J'ai récemment terminé le livre de Joe et je l'ai apprécié. Depuis, j'ai commencé à coder une application logicielle en temps réel avec erlang et je dois dire que l'utilisation de gen_server me laisse un peu perplexe.

Quand devrais-je utiliser gen_server au lieu d'un simple module sans état? Je définis un module sans état comme suit: - Un module qui prend son état comme paramètre (un peu comme ETS / DETS) plutôt que de le garder en interne (comme gen_server)

Dites pour un module de type gestionnaire de factures, doit-il être initialisé et renvoyer un état que je lui transmettrais par la suite? SomeState = InvoiceManager: Init (), SomeState = InvoiceManager: AddInvoice (SomeState, AnInvoiceFoo).

Supposons que j’ai besoin de plusieurs instances de l’état du gestionnaire de factures (par exemple, mon application gère plusieurs entreprises ayant chacune leur propre facture), si chacune d’entre elles dispose d’un serveur gen_server avec un état interne pour gérer leurs factures ou s’il serait plus approprié d’avoir simplement le module sans état ci-dessus?

Où se trouve la ligne de démarcation entre les deux?

(Notez que l'exemple de gestion des factures ci-dessus n'est qu'un exemple pour illustrer ma question.)

Était-ce utile?

La solution

Cela dépend fortement de vos besoins et de la conception de votre application. Lorsque vous avez besoin d'un état partagé entre processus, vous devez utiliser process pour conserver cet état. Alors gen_server , gen_fsm ou un autre gen _ * est votre ami. Vous pouvez éviter cette conception lorsque votre application n'est pas concurrente ou si cette conception ne vous apporte pas d'autres avantages. Par exemple, casser votre candidature aux processus conduira à une conception plus simple. Dans d’autres cas, vous pouvez parfois choisir une conception de processus unique et utiliser " stateless " modules de performance ou autres. " apatride " Le module est le meilleur choix pour des tâches très simples sans état (purement fonctionnelles). gen_server est souvent le meilleur choix pour les pensées qui semblent naturellement "traiter". Vous devez l’utiliser lorsque vous souhaitez partager quelque chose entre des processus (l’utilisation de processus peut être limitée par l’évolutivité ou la simultanéité).

Autres conseils

Je ne pense pas vraiment que vous puissiez faire la distinction entre ce que vous appelez un module sans état et gen_server. Dans les deux cas, il existe une boucle de réception récursive qui porte l'état dans au moins un argument. Cette boucle principale gère les demandes, fonctionne en fonction des demandes et, si nécessaire, renvoie les résultats aux demandeurs. La boucle principale traitera probablement également un certain nombre de demandes administratives qui ne font peut-être pas partie de l'API / du protocole principal.

La différence est que gen_server extrait la boucle de réception principale et permet à l’utilisateur de n’écrire que le code utilisateur actuel . Il gérera également pour vous de nombreuses fonctions administratives d'OTP. La principale différence est que le code utilisateur se trouve dans un autre module, ce qui signifie que vous visualisez l'état transmis, plus facilement. Sauf si vous parvenez à écrire votre code dans une grande boucle de réception et à ne pas appeler d'autres fonctions pour effectuer le travail, il n'y a pas de réelle différence.

La meilleure méthode dépend beaucoup de ce dont vous avez besoin. Utiliser gen_server simplifiera votre code et vous apportera une fonctionnalité supplémentaire "gratuitement". mais cela peut être plus restrictif. Rouler vous-même vous donnera plus de puissance mais vous donnez aussi plus de possibilités de tout gâcher. C'est probablement un peu plus rapide aussi. De quoi avez-vous besoin?

Ayant utilisé les deux modèles, je dois dire que l’utilisation du gen_server fourni m’aide à rester plus facilement structuré. Je suppose que c’est la raison pour laquelle il est inclus dans la pile d’outils OTP: gen_server est un bon moyen d’extraire la plaque de chaudière répétitive.

Si vous avez partagé l'état de plusieurs processus, vous devriez probablement utiliser gen_server. Si l'état est juste local à un processus, un module sans état fera l'affaire.

Je suppose que vos factures (ou ce qu’elles représentent) doivent être persistantes. Elles se retrouveraient donc dans une table ETS / Mnesia. Si tel est le cas, vous devez créer un module sans état dans lequel vous placerez votre API pour accéder à la table des factures.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top