2009-06-29 4 views
10

J'ai un serveur qui utilise la structure des acteurs distants pour communiquer avec plusieurs clients. Comme mentionné dans this question, j'ai du mal à suivre quand un client disparaît. Par conséquent, mon serveur tente toujours d'envoyer des messages à des clients inexistants.Que fait le framework d'acteur distant en essayant d'écrire sur un client qui n'est plus là?

  • Est-ce un problème? (Je ne vois aucune exception - mais je suppose qu'il y aura des problèmes de mémoire si mon serveur est de longue durée)
  • Comment puis-je détecter qu'un message est envoyé à un client qui n'écoute plus? (Si je veux mettre en place une sorte de nettoyage de connexion)
+0

Avez-vous regardé le membre trapExit du trait Acteur? Il est documenté ici: http: //www.scala-lang.org/docu/files/acteurs-api/actors_api_guide_1.html – djondal

Répondre

1

OK, je vais risquer quelque chose ici. Disclaimer: malgré ce que vous allez lire ci-dessous, vous pouvez vouloir start here. Je ne suis pas familier avec scala, mais il utilise des principes similaires à Erlang et je me sens un peu à l'aise là-bas. La chose qui me déroute dans votre question n'a cependant rien à voir avec cela. Mais plus avec la relation client-serveur que vous semblez établir.

Par définition, un serveur ne continue pas d'envoyer des messages au client à moins qu'il ne reçoive une requête. C'est-à-dire que la classe d'acteur serveur doit être construite (pas nécessairement toujours) autour d'instructions de cas qui vérifient le message reçu et agissent en conséquence. Donc, dans ce contexte, le client est existant et le serveur ne devrait pas s'en soucier et envoyer à la place son message de réponse normalement, parce que le client a juste fait sa présence avec une requête.

Donc, si votre serveur essaie toujours d'envoyer des messages aux clients, malgré qu'ils aient été fermés, il me semble qu'il essaie d'envoyer des messages malgré le fait qu'il n'ait reçu aucune requête. Ceci est fondamentalement faux dans le contexte d'une relation client-serveur. Le serveur ne devrait réagir que sur demande. Sinon, il prend le rôle du client.

Dans tous les cas, vous pouvez (et) définir une fin à toute conversation client-serveur. Cela aidera à libérer des ressources et à mettre fin aux connexions établies. Pour cet effet:

  1. Votre acteur client doit envoyer un arrêt message au serveur et mettre fin à son exécution avec quelle que soit la fonction de sortie scala a mis en œuvre pour la classe acteur.

  2. À la réception d'un message d'arrêt, l'acteur serveur doit ne pas répondre au client. Au lieu de cela, il devrait faire son nettoyage (le cas échéant) et terminer l'exécution de la même manière que l'acteur client.

De cette façon, vous assurez une terminaison correcte de tous les acteurs impliqués et une libération correcte des ressources.

J'espère que cela a aidé d'une manière ou d'une autre. Malheureusement, je ne suis pas familier avec Scala lui-même. Sinon, je pourrais apporter du code. Mais le lien ci-dessus devrait aider, espérons-le.

+2

J'ai bien peur que cette approche ne marche pas. Vous ne pouvez pas garantir que la méthode * stop * est envoyée au serveur et lorsque cela se produit, la boîte aux lettres du proxy côté serveur * de l'acteur client se remplit et le serveur finit par tomber en panne en raison d'un manque de mémoire. J'ai trouvé que le seul mécanisme est pour les clients de renouveler un "bail" sur une minuterie: le serveur vérifie périodiquement les baux et tous ceux expirés sont jetés –

+0

+1. Je suis d'accord, oxbow. Mais je code toujours cela autour d'un message d'arrêt pour une résiliation normale et plus rapide dans les cas où le message est reçu. –

Questions connexes