Nova implementação de tracker BitTorrent escrita em Elixir
(github.com/Dahrkael)- ExTracker é um tracker BitTorrent feito em Elixir; o trabalho ainda está em andamento, mas ele funciona e informa explicitamente que ainda não está pronto para uso industrial em larga escala
- As metas de desempenho são alta performance com uso de todos os núcleos disponíveis, operação baseada em armazenamento em memória, cerca de 200MB de RAM por 1 milhão de peers e uma estrutura que pode ser executada sem configuração separada
- Em relação aos BEPs do BitTorrent, implementa BEP 0, BEP 15, BEP 23, BEP 7, BEP 21, BEP 24, BEP 41, BEP 48 e BEP 52; alguns itens, como Private Torrents, ainda não foram implementados ou estão parcialmente implementados
- Suporta HTTPS, backup de banco de dados em disco e execução com Docker; não oferece suporte a WebTorrent, e whitelist/blacklist, gerenciamento de peers, metrics e GeoIP estão em estado de implementação parcial
- Há três formas de execução: rodar diretamente do código-fonte, fazer um build de release manualmente ou executar a imagem Docker; em contêineres, a configuração pode ser feita por variáveis de ambiente em vez de
runtime.exs
Estado e objetivos do ExTracker
- ExTracker é uma implementação de tracker BitTorrent apresentada como “The Bittorrent Tracker made in Elixir”
- O projeto está em estado de Work In Progress
- É informado explicitamente que ainda não está pronto para uso industrial em larga escala
- Atualmente já funciona
- Uma instância de teste está em execução em
extracker.dahrkael.net:6969, com os recursos atuais ativados
Principais recursos
- Desempenho e facilidade de operação são apresentados como recursos centrais
- Alta performance: usa todos os núcleos disponíveis
- Usa armazenamento em memória
- O uso de memória é de cerca de 200MB de RAM por 1 milhão de peers
- Zero setup: o objetivo é funcionar imediatamente ao ser executado
Estado de suporte aos BEPs do BitTorrent
- A indicação de implementação é dividida em
✅ Done,🔰 Partially,🔲 Not Yet,❌ Won't do -
BEPs concluídos
- BEP 0: The BitTorrent Protocol Specification
- BEP 15: UDP Tracker Protocol
- BEP 23: Tracker Returns Compact Peer Lists
- BEP 7: IPv6 Tracker Extension
- BEP 21: Extension for partial seeds
- BEP 24: Tracker Returns External IP
- BEP 41: UDP Tracker Protocol Extensions
- BEP 48: Tracker Protocol Extension: Scrape
- BEP 52: The BitTorrent Protocol Specification v2
-
BEPs não implementados ou excluídos
- BEP 27: Private Torrents ainda não foi implementado
- BEP 31: Tracker Failure Retry Extension ainda não foi implementado
- BEP 8: Tracker Peer Obfuscation é um item que não será implementado
Outros recursos e limitações
- Recursos concluídos
-
Suporte a HTTPS
- Backup de banco de dados em disco
- Recursos não suportados
- WebTorrent
- Recursos parcialmente implementados
-
Whitelist/blacklist de infohash
- gerenciamento de peers: interval enforcement, cleanup, banning etc.
-
Metrics
- Suporte a GeoIP: para estatísticas e limitação de peers
- Sugestões de recursos podem ser enviadas em Issues
-
Como executar
-
Executar diretamente do código-fonte
- Esse método exige que Erlang e Elixir estejam instalados no sistema
- Clone o repositório
git clone https://github.com/Dahrkael/ExTracker.git && cd ExTracker- Se necessário, edite config/runtime.exs
- O comando para executar é
MIX_ENV=prod iex -S mix
-
Build de release
- No momento não há builds de release oficiais; é possível criar e distribuir sua própria release
- Após clonar o repositório, faça o build de acordo com o sistema operacional
- Linux:
MIX_ENV=prod mix release extracker - Windows:
MIX_ENV=prod mix release extrackerw - Os arquivos de release são gerados na pasta
_build/prod/rel/extracker - Ao mover para outra máquina, o SO e a arquitetura devem ser os mesmos
- Se necessário, ajuste a configuração em
releases/{VERSION}/runtime.exs - O comando para executar é
bin/extracker start
-
Executar com Docker
- A imagem Docker fornecida pode ser executada diretamente
docker run ghcr.io/dahrkael/extracker:latest- Também pode ser usado com docker-compose, e há um arquivo compose de exemplo
- Como é difícil ajustar a configuração alterando
runtime.exsdentro do contêiner, também é possível configurar por variáveis de ambiente - A lista completa de variáveis de ambiente pode ser vista no arquivo compose de exemplo
Licença
- O ExTracker é distribuído sob os termos da Apache License 2.0
- Para mais detalhes, consulte o arquivo LICENSE no repositório
1 comentários
Opiniões no Hacker News
Eu esperava um design com OTP em primeiro lugar, mas achei uma pena que o código pareça mais procedural, mexendo diretamente com ETS ou com uma Application baseada em ETS em quase todas as operações
Para aprender a projetar serviços com OTP em Elixir ou outras linguagens da BEAM, vale ver "Designing Elixir Systems with OTP", de James Edward Gray e Bruce Tate, e "Functional Web Development with Elixir, OTP, and Phoenix", de Lance Halvorsen
No fim, um tracker de torrent é mais parecido com um banco de dados especializado, e o objetivo principal é processar dados o mais rápido possível
Ainda assim, vou dar uma lida nesses livros
Hoje ele tem mais a ver com software que tem características de aplicações de telecomunicações do que com telecomunicações em si; se metade da grandeza do Erlang é concorrência e distribuição, e a outra metade é a capacidade de tratamento de erros, o framework OTP pode ser visto como essa “terceira metade”
https://learnyousomeerlang.com/what-is-otp
Se for uma configuração de servidor único, ETS é 100% a escolha certa e, embora não vá escalar horizontalmente, vai escalar verticalmente muito bem
De qualquer forma, na maior parte dos casos provavelmente é YAGNI
Pode haver casos em que GenServers adicionais ou
gen_statemse encaixem muito bem, mas, em muitos usos de Elixir e Phoenix, não é preciso chegar a escolhas arquiteturais sofisticadasPorque o runtime já faz coisas sofisticadas o suficiente por você
ETS é embutido no OTP, então não entendo por que usar ETS não seria OTP-first
Também não vejo muito qual seria o problema de usar ETS; é só um armazenamento em memória
Dei uma passada pelo código e não achei que ele parecesse próximo de um estilo procedural
Ficou bem feito. Seria bom migrar de
IO.putspara Logger e considerar adicionar OTel[0] https://hexdocs.pm/logger/1.18.4/Logger.html
[1] https://hexdocs.pm/telemetry/readme.html
Elixir é muito bom. Estou criando um motor de notificações bacana em Elixir agora, e é realmente excelente
Elixir realmente precisa de um motor de notificações melhor
Parabéns pelo lançamento. Fiquei curioso se você pode detalhar como ele se comporta em comparação com o opentracker
Tenho bastante interesse em pontos como desempenho
O ponto em que o ExTracker brilha é quando a contagem de núcleos começa a chegar a dois dígitos
Mas ainda preciso fazer benchmarks adequados
Parece bom. Vou conferir depois
Alguns anos atrás fiz um tracker básico em Elixir; o código está aqui: https://github.com/aalin/mr_torrent
Interessante. Criei algo parecido em TypeScript para aprender mais sobre BitTorrent e depois refiz em Rust para aprender Rust: https://github.com/ckcr4lyf/kiryuu
Mas eu simplesmente usei Redis como banco de dados. Parece que este projeto mantém o banco inteiro em memória; fiquei curioso se houve decisões de design interessantes ou problemas encontrados ao fazer isso
Minha solução com Redis não parece tão boa, porque acho que ela não randomiza os peers em announces subsequentes
Dá para ler e escrever os dados de cada peer simultaneamente em seus próprios processos, minimizando contenção e latência
A única parte processada de forma sequencial é quando um novo swarm é criado pela primeira vez, mas isso não acontece com frequência, então tudo bem
Infelizmente, não há suporte nativo para pegar diretamente uma linha aleatória da tabela; por enquanto, pego o swarm inteiro e escolho um subconjunto aleatório: https://github.com/Dahrkael/ExTracker/blob/master/lib/ex_tra...
Seria bom se você pudesse explicar o que são DHT e PEX. É difícil pesquisar por "tracker PEX"
Assim, uma localização central ou trackers públicos deixam de ser necessários
Legal. Fiquei curioso se você gostaria de usar Elixir como trabalho principal
Também conheço Rust e Go. Estão contratando?
Fiquei curioso para saber como você começou, se consultou outros projetos, quanto tempo levou e até que ponto acha que as funcionalidades funcionam em comparação com algo como qBittorrent
Também dei uma olhada no código de outros trackers, mas em geral eram complicados demais ou simples demais, então não ajudaram muito
Até agora, é o resultado de 3 meses de procrastinação vingativa do sono
Isto não é um cliente como o qBittorrent, mas tenho uma ideia de projeto futuro de cliente voltado a seedbox
Testei, mas não consegui fazer o HTTPS funcionar
No console fica aparecendo
04:43:20.160 [warning] invalid 'event' parameter: size: 6 value: "paused", mas parece estar funcionandoEu também queria ver estatísticas de HTTP, mas UDP também está ok. Só que eu estou com UDP desativado
"paused"faz parte da BEP 21Ele é enviado quando o cliente informa ao tracker que ainda não está em estado concluído, mas não fará mais downloads
Por exemplo, quando o usuário quer apenas alguns arquivos do torrent
Pelo README do projeto, o suporte à BEP 21 ainda não foi implementado
Estou usando uma biblioteca de terceiros para o servidor web, então ainda preciso descobrir o jeito correto
Para usar HTTPS, é preciso fornecer um caminho de certificado válido em
:https_keyfile, mas, por enquanto, se precisar de HTTPS, recomendo colocar Caddy ou Nginx na frente do trackerA integração com certbot também está planejada, mas não tem prioridade alta porque a maioria dos peers de torrent usa UDP