dimanche 14 février 2010

Accès concurrent aux listes de propriétés

Je n'allais quand même pas laisser de côté un tel sujet! Récapitulons. Nous avons:



- Une base de données contenant les listes
- Un serveur de listes (unique), qui fournit l'interface vers la base
- Les serveurs, qui communiquent avec le serveur de listes pour récupérer et sauver les listes
- Les clients
- L'interface d'administration Web, qui cause directement à la base de données.

Les clients ne doivent pas modifier les listes directement, mais indiquer leurs actions aux serveurs, qui modifient les listes en fonction. Les serveurs possèdent un cache des listes, et récupèrent auprès du serveur de listes celles dont ils ont besoin. Tentons de dérouler un exemple pour voir comment tout ceci peut fonctionner.

Le Roi Minablos se connecte sur un serveur. Le serveur récupère auprès du serveur de listes l'ensemble des listes dont il aura besoin, c'est à dire la liste du personnage, les listes parentes, les sous-listes référencées dans la liste (par exemple l'inventaire), et ainsi de suite (encore un diagramme, je suis chaud sur Dia, là!).



Les premières fois, l'on aura probablement une bonne partie du monde à télécharger depuis le serveur de liste, mais, le cache aidant, les serveurs seront rapidement à jour. Pour chaque liste, le serveur détermine s'il a besoin d'un accès en lecture seule, ou d'un accès en écriture, en différenciant les listes correspondant à des objets réels, qu'il gère (le Roi Minablos, une bouteille d'huile d'olive), et les objets virtuels, qui correspondent à des attributs et des propriétés générales du monde (ainsi, la liste "huile d'olive", dont dérive la bouteille, contient les propriétés générale de l'huile d'olive, et n'est accessible qu'en lecture seule).

Le Roi Minablos se saisit d'une bouteille d'huile d'olive, et envoie la requête correspondante au serveur. Le serveur modifie la liste du Roi Minablos, en y référençant la bouteille, et sauve les nouvelles listes auprès du serveur de liste.

Plus compliqué: le Roi Minablos fait pousser un olivier. C'est un cas à part, puisque le serveur doit créer une nouvelle liste. Plutôt que de gérer un long appel au serveur de listes, l'idée est pour le serveur de demander au démarrage un grand nombre de listes vides, dont il peut user comme bon lui semble, et d'en demander d'autres, de manière asynchrone, quand sa réserve s'épuise. Dans le cas de notre olivier, le serveur assigne une de ses listes vides, la fait dériver de l'objet olivier, lui met le Roi Minablos comme propriétaire, puis la référence auprès du serveur de liste.

Encore plus compliqué! Le maître de jeu gère une malédiction lancée par un sorcier maléfique, qui a rendu toutes les pommes empoisonnées. Il modifie dans son interface d'administration les propriétés des pommes. L'interface modifie la base, qui réveille le serveur de listes, lequel rafraîchit ses listes, et envoie des notifications à tous les serveurs qui avaient dans leur cache la liste des pommes. La prochaine fois qu'un joueur voudra croquer dedans, ça fera mal aux gencives!

2 commentaires:

Dongorath a dit…

Question : les serveurs gèrent-ils chacun un monde différent ? La question sous-jacente étant quid des mises à jours de listes en cache inter-serveurs ? Exemple : un personnage A rattaché au serveur SA pouvant voir les caractéristiques d'un autre joueur B dont le client est rattaché à un autre serveur SB. Le cheminement que je voie est SA demande la liste de B au serveur de listes, mais si A modifie ses caractéristiques d'une manière ou d'une autre, celles-ci sont modifiées sur SB et répercuté sur le serveur de liste de façon plus ou moins synchrone, mais comment SA est-il notifié de ces changements ?
C'est surement possible assez facilement, mais mon inexpérience me fait penser que la connaissance des états des serveurs par le serveur de liste peut rapidement être très consommateur en ressources et ainsi plomber les gains obtenus par la mise en cache des listes par rapport à des accès en BdD directs.

Si chaque serveur est lié à un monde donné, la question se posera peut-être le jour où l'on permettra les communications inter-serveurs (ex: les champs de batailles inter-serveurs de WoW pour ne pas le citer). :)

M87 a dit…

Dans le système que j'ai décrit, une liste ne peut être possédée en écriture que par un seul serveur. Ceci veut dire par exemple qu'il n'est pas possible de transférer un objet entre des personnages qui seraient sur deux serveurs différents. Je pense donc que chaque serveur correspondrait à une zone séparée, tout en laissant la possibilité à un personnage de passer d'une zone à l'autre (dans ce cas, les listes sont rendues par l'ancienne zone, puis reprises par la nouvelle zone).

Pour permettre de meilleures interactions inter-zones, il va donc falloir ruser! Par exemple, le marché se trouverait sur une seule zone. Un personnage voulant vendre un objet peut l'y déposer, l'objet apparentant maintenant à une liste de la zone du marché. Le personnage peut ensuite changer de zone et faire ce que bon lui semble. Quand l'objet est vendu, le personnage reçoit une notification (via un service de messages, indépendant du système de listes), et doit se déplacer dans la zone du marché pour obtenir ses sous.

Les performances, c'est la grosse question :) Pour l'instant, je ne m'inquiète pas trop. L'on pourra penser à des systèmes multicast, ou du p2p entre les zones.