Fork of Paper que adiciona multithreading regionalizado ao servidor dedicado.
Folia agrupa pedaços carregados próximos para formar uma "região independente". Consulte a documentação do PaperMC para obter detalhes exatos sobre como o Folia agrupará pedaços próximos. Cada região independente tem seu próprio tick loop, que é marcado na taxa de tick regular do Minecraft (20TPS). Os loops de tick são executados em um pool de threads em paralelo. Não existe mais thread principal, pois cada região possui efetivamente seu próprio "thread principal" que executa todo o loop de tick.
Para um servidor com muitos jogadores espalhados, o Folia criará muitas regiões espalhadas e marcará todas elas em paralelo em um threadpool de tamanho configurável. Portanto, o Folia deve ser bem dimensionado para servidores como este.
Folia também é um projeto próprio, não será incorporado ao Paper em um futuro próximo.
Uma visão geral mais detalhada, mas abstrata: Visão geral do projeto.
Os tipos de servidores que distribuem naturalmente os jogadores, como skyblock ou SMP, serão os que mais se beneficiarão com o Folia. O servidor também deve ter um número considerável de jogadores.
Idealmente, pelo menos 16 núcleos (não threads).
Primeiro, é recomendado que o mundo seja pré-gerado para que o número de threads de trabalho do sistema de partes necessários seja bastante reduzido.
A seguir está uma estimativa muito aproximada baseada nos testes feitos antes do Folia ser lançado no servidor de teste que executamos, que teve um pico de aproximadamente 330 jogadores. Portanto, não é exato e exigirá ajustes adicionais - basta tomá-lo como ponto de partida.
O número total de núcleos disponíveis na máquina deve ser levado em consideração. Em seguida, aloque threads para:
-XX:ConcGCThreads=n
. Não confunda este sinalizador com -XX:ParallelGCThreads=n
, pois os threads paralelos do GC só são executados quando o aplicativo é pausado pelo GC e, como tal, não devem ser levados em consideração.Depois de toda essa alocação, os núcleos restantes no sistema até 80% da alocação (total de threads alocados <80% da CPU disponível) podem ser alocados para tickthreads (na configuração global, threaded-regions.threads).
A razão pela qual você não deve alocar mais de 80% dos núcleos é devido ao fato de que os plugins ou mesmo o servidor podem fazer uso de threads adicionais que você não pode configurar ou mesmo prever.
Além disso, tudo o que foi dito acima é um palpite aproximado com base na contagem de jogadores, mas é muito provável que a alocação de threads não seja ideal e você precisará ajustá-la com base no uso dos threads que acabar vendo.
Não há mais tópico principal. Espero que cada plugin existente exija algum nível de modificação para funcionar no Folia. Além disso, qualquer tipo de multithreading introduz possíveis condições de corrida nos dados mantidos pelo plug-in - portanto, é provável que haja alterações que precisam ser feitas.
Portanto, tenha suas expectativas de compatibilidade em 0.
Atualmente, existem muitas APIs que dependem do thread principal. Espero que basicamente nenhum plugin compatível com Paper seja compatível com Folia. No entanto, existem planos para adicionar API que permitiria que os plug-ins do Folia fossem compatíveis com o Paper.
Por exemplo, o Agendador Bukkit. O Bukkit Scheduler depende inerentemente de um único thread principal. O RegionScheduler da Folia e o EntityScheduler da Folia permitem o agendamento de tarefas para o "próximo tick" de qualquer região que "possui" um local ou uma entidade. Eles poderiam ser implementados em Paper normal, exceto que são agendados para o thread principal - em ambos os casos, a execução da tarefa ocorrerá no thread que "possui" o local ou entidade. Este conceito se aplica em geral, já que o documento atual (threaded único) pode ser visto como uma “região” gigante que abrange todos os pedaços em todos os mundos.
Ainda não está decidido se esta API será adicionada diretamente ao Paper ou ao Paperlib.
Primeiro, o Folia quebra muitos plugins. Para ajudar os usuários a descobrir quais plugins funcionam, apenas os plugins que foram explicitamente marcados pelo(s) autor(es) para trabalhar com o Folia serão carregados. Ao colocar "folia-supported: true" no plugin.yml do plugin, os autores do plugin podem marcar seu plugin como compatível com multithreading regionalizado.
A outra regra importante é que as regiões funcionem em paralelo e não simultaneamente . Eles não compartilham dados, não esperam compartilhar dados, e o compartilhamento de dados causará corrupção de dados. O código que está em execução em uma região sob nenhuma circunstância pode acessar ou modificar dados que estão em outra região. Só porque multithreading está no nome, isso não significa que agora tudo é thread-safe. Na verdade, existem apenas algumas coisas que foram tornadas seguras para threads para que isso acontecesse. Com o passar do tempo, o número de verificações de contexto de thread só aumentará, mesmo que isso acarrete uma penalidade de desempenho - ninguém usará ou desenvolverá uma plataforma de servidor com muitos bugs, e a única maneira de prevenir e encontrar essas bugs é fazer com que acessos ruins falhem na origem do acesso ruim.
Isso significa que os plug-ins compatíveis com Folia precisam aproveitar as vantagens de APIs como RegionScheduler e EntityScheduler para garantir que seu código esteja sendo executado no contexto de thread correto.
Em geral, é seguro assumir que uma região possui dados de pedaços em aproximadamente 8 pedaços da origem de um evento (ou seja, o jogador quebra o bloco, provavelmente pode acessar 8 pedaços ao redor desse bloco). Mas isso não é garantido - os plug-ins devem aproveitar as vantagens da próxima API de verificação de thread para garantir o comportamento correto.
A única garantia de segurança do thread vem do fato de que uma única região possui dados em determinados blocos - e se essa região estiver funcionando, ela terá acesso total a esses dados. Esses dados são especificamente dados de entidade/pedaço/poi e não estão totalmente relacionados a QUALQUER dado do plugin.
As regras normais de multithreading se aplicam aos dados que os plug-ins armazenam/acessam seus próprios dados ou de outro plug-in - eventos/comandos/etc. são chamados em paralelo porque as regiões estão funcionando em paralelo (NÃO PODEMOS chamá-los de forma síncrona, pois isso abre problemas de impasse e prejudicaria o desempenho). Não há maneiras fáceis de escapar disso, depende apenas de quais dados estão sendo acessados. Às vezes, uma coleção simultânea (como ConcurrentHashMap) é suficiente, e muitas vezes uma coleção simultânea usada descuidadamente apenas oculta problemas de threading, que se tornam quase impossíveis de depurar.
Para entender adequadamente as adições de API, leia a visão geral do projeto.
Para entender adequadamente as adições de API, leia a visão geral do projeto.
Regras gerais:
Os comandos para entidades/jogadores são chamados na região que possui a entidade/jogador. Os comandos do console são executados na região global.
Eventos envolvendo uma única entidade (ou seja, bloco de quebras/locações de jogadores) são chamados na entidade proprietária da região. Eventos que envolvem ações em uma entidade (como danos à entidade) são invocados na região que possui a entidade alvo.
O modificador async para eventos está obsoleto - todos os eventos disparados de regiões ou da região global são considerados síncronos , mesmo que não haja mais 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 >
O arquivo PATCHES-LICENSE descreve a licença para patches de API e servidor, encontrada em ./patches
e seus subdiretórios, exceto quando indicado o contrário.
O fork é baseado no exemplo de fork do PaperMC encontrado aqui. Como tal, contém modificações neste projeto, consulte o repositório para obter informações de licença de arquivos modificados.