Fork of Paper qui ajoute le multithreading régionalisé au serveur dédié.
Folia regroupe les morceaux chargés à proximité pour former une « région indépendante ». Consultez la documentation PaperMC pour plus de détails exacts sur la façon dont Folia regroupera les morceaux à proximité. Chaque région indépendante possède sa propre boucle de tick, qui est cochée au tickrate Minecraft normal (20TPS). Les boucles de ticks sont exécutées sur un pool de threads en parallèle. Il n'y a plus de thread principal, car chaque région possède effectivement son propre "thread principal" qui exécute toute la boucle de tick.
Pour un serveur avec de nombreux joueurs répartis, Folia créera de nombreuses régions réparties et les cochera toutes en parallèle sur un pool de threads de taille configurable. Ainsi, Folia devrait bien évoluer pour des serveurs comme celui-ci.
Folia est également son propre projet, celui-ci ne sera pas fusionné avec Paper dans un avenir prévisible.
Un aperçu plus détaillé mais abstrait : Aperçu du projet.
Les types de serveurs qui répartissent naturellement les joueurs, comme skyblock ou SMP, bénéficieront le plus de Folia. Le serveur devrait également avoir un nombre important de joueurs.
Idéalement, au moins 16 cœurs (pas de threads).
Premièrement, il est recommandé que le monde soit pré-généré afin que le nombre de threads de travail système requis soit considérablement réduit.
Ce qui suit est une estimation très approximative basée sur les tests effectués avant la sortie de Folia sur le serveur de test que nous avons exécuté et qui comptait environ 330 joueurs en pointe. Ce n’est donc pas exact et nécessitera des ajustements supplémentaires – prenez-le simplement comme point de départ.
Le nombre total de cœurs disponibles sur la machine doit être pris en compte. Ensuite, allouez des threads pour :
-XX:ConcGCThreads=n
. Ne confondez pas cet indicateur avec -XX:ParallelGCThreads=n
, car les threads GC parallèles ne s'exécutent que lorsque l'application est suspendue par GC et ne doivent donc pas être pris en compte.Après toute cette allocation, les cœurs restants sur le système jusqu'à 80 % d'allocation (total des threads alloués < 80 % des processeurs disponibles) peuvent être alloués aux tickthreads (sous la configuration globale, threaded-regions.threads).
La raison pour laquelle vous ne devez pas allouer plus de 80 % des cœurs est due au fait que les plugins ou même le serveur peuvent utiliser des threads supplémentaires que vous ne pouvez pas configurer ni même prédire.
De plus, tout ce qui précède n'est qu'une estimation approximative basée sur le nombre de joueurs, mais il est très probable que l'allocation des threads ne sera pas idéale et vous devrez la régler en fonction de l'utilisation des threads que vous finirez par voir.
Il n'y a plus de fil conducteur. Je m'attends à ce que chaque plugin existant nécessite un certain niveau de modification pour fonctionner dans Folia. De plus, le multithreading de toute nature introduit des conditions de concurrence possibles dans les données détenues par le plugin - il y aura donc forcément des modifications à apporter.
Alors, ayez vos attentes en matière de compatibilité à 0.
Actuellement, de nombreuses API s’appuient sur le thread principal. Je m'attends à ce qu'aucun plugin compatible avec Paper ne soit compatible avec Folia. Cependant, il est prévu d'ajouter une API qui permettrait aux plugins Folia d'être compatibles avec Paper.
Par exemple, le planificateur Bukkit. Le planificateur Bukkit repose intrinsèquement sur un seul thread principal. RegionScheduler de Folia et EntityScheduler de Folia permettent de planifier des tâches au « prochain tick » de n'importe quelle région « propriétaire » d'un emplacement ou d'une entité. Celles-ci pourraient être implémentées sur Paper standard, sauf qu'elles sont planifiées sur le thread principal - dans les deux cas, l'exécution de la tâche aura lieu sur le thread qui "possède" l'emplacement ou l'entité. Ce concept s'applique en général, car le papier actuel (à thread unique) peut être considéré comme une « région » géante qui englobe tous les morceaux de tous les mondes.
Il n'est pas encore décidé s'il faut ajouter cette API directement à Paper lui-même ou à Paperlib.
Premièrement, Folia casse de nombreux plugins. Pour aider les utilisateurs à déterminer quels plugins fonctionnent, seuls les plugins qui ont été explicitement marqués par le ou les auteurs pour fonctionner avec Folia seront chargés. En plaçant "folia-supported: true" dans le plugin.yml du plugin, les auteurs de plugins peuvent marquer leur plugin comme compatible avec le multithreading régionalisé.
L'autre règle importante est que les régions fonctionnent en parallèle et non simultanément . Ils ne partagent pas de données, ils ne s’attendent pas à partager des données, et le partage de données entraînera une corruption des données. Le code exécuté dans une région ne peut en aucun cas accéder ou modifier des données se trouvant dans une autre région. Ce n’est pas parce que le multithreading est dans le nom que tout est désormais thread-safe. En fait, seules quelques éléments ont été rendus thread-safe pour que cela se produise. Au fil du temps, le nombre de vérifications de contexte de thread ne fera qu'augmenter, même si cela entraîne une perte de performances - personne n'utilisera ou ne développera pour une plate-forme serveur qui est boguée comme l'enfer, et c'est le seul moyen de les empêcher et de les trouver. bugs est de faire échouer les mauvais accès à la source du mauvais accès.
Cela signifie que les plugins compatibles Folia doivent tirer parti des API telles que RegionScheduler et EntityScheduler pour garantir que leur code s'exécute sur le bon contexte de thread.
En général, il est prudent de supposer qu'une région possède environ 8 fragments de données provenant de la source d'un événement (c'est-à-dire que le joueur brise le bloc, peut probablement accéder à 8 fragments autour de ce bloc). Mais cela n’est pas garanti – les plugins devraient profiter de la prochaine API de vérification des threads pour garantir un comportement correct.
La seule garantie de sécurité des threads vient du fait qu'une seule région possède des données dans certains morceaux - et si cette région fonctionne, alors elle a un accès complet à ces données. Ces données sont spécifiquement des données d'entité/morceaux/poi et n'ont aucun rapport avec AUCUNE donnée de plugin.
Les règles normales de multithreading s'appliquent aux données que les plugins stockent/accèdent à leurs propres données ou à celles d'un autre plugin - événements/commandes/etc. sont appelés en parallèle parce que les régions fonctionnent en parallèle (nous NE POUVONS PAS les appeler de manière synchrone, car cela ouvrirait des problèmes de blocage et handicaperait les performances). Il n’y a pas de solution simple pour s’en sortir, cela dépend uniquement des données auxquelles on accède. Parfois, une collection simultanée (comme ConcurrentHashMap) suffit, et souvent une collection simultanée utilisée avec négligence ne fera que masquer les problèmes de thread, qui deviennent alors presque impossibles à déboguer.
Pour bien comprendre les ajouts d'API, veuillez lire la présentation du projet.
Pour bien comprendre les ajouts d'API, veuillez lire la présentation du projet.
Règles générales générales :
Les commandes pour les entités/joueurs sont appelées sur la région qui possède l'entité/le joueur. Les commandes de console sont exécutées sur la région globale.
Les événements impliquant une seule entité (c'est-à-dire les pauses des joueurs/blocages de places) sont appelés sur l'entité propriétaire de la région. Les événements impliquant des actions sur une entité (telles que des dommages à l'entité) sont invoqués sur la région propriétaire de l'entité cible.
Le modificateur async pour les événements est obsolète : tous les événements déclenchés depuis les régions ou la région globale sont considérés comme synchrones , même s'il n'y a plus de thread principal.
< repository >
< id >papermc</ id >
< url >https://repo.papermc.io/repository/maven-public/</ url >
</ repository >
< dependency >
< groupId >dev.folia</ groupId >
< artifactId >folia-api</ artifactId >
< version >1.20.1-R0.1-SNAPSHOT</ version >
< scope >provided</ scope >
</ dependency >
Le fichier PATCHES-LICENSE décrit la licence pour les correctifs API et serveur, trouvés dans ./patches
et ses sous-répertoires, sauf indication contraire.
Le fork est basé sur l'exemple de fork de PaperMC trouvé ici. En tant que tel, il contient des modifications dans ce projet, veuillez consulter le référentiel pour les informations de licence des fichiers modifiés.