O novo backend do TSBOARD, um criador de comunidades open source: GOAPI
(github.com/sirini)Há cerca de 7 meses, apresentei o projeto TSBOARD pela primeira vez.
Na época, tanto o frontend quanto o backend eram escritos em TypeScript, e o runtime Bun era usado para executar o backend.
No entanto, por vários motivos, acabei refazendo o backend do zero e o estou publicando em um repositório separado no GitHub, distinto do projeto TSBOARD existente. Esse novo backend foi escrito em Go e será distribuído junto com a versão oficial do TSBOARD em formato binário.
Por que refiz o backend?
- O runtime Bun entrega um desempenho realmente excelente. Mas, apesar da proposta de ser um toolkit tudo-em-um, o gerenciamento de pacotes ainda não alcança o nível do npm.
- Por causa disso, para usar o TSBOARD eram necessários dois runtimes: Node.js e Bun. Além de ser trabalhoso, isso também era inconveniente para os usuários.
- Hoje isso já foi corrigido, mas no começo houve um problema em que ele não rodava em CPUs virtuais, e a situação de eu, como desenvolvedor, não conseguir nem mesmo subir em outro servidor foi crítica.
- (Como outras pessoas apontaram) até dá para resolver com orquestração, mas eu queria ir além das limitações inerentes de um runtime JS single-thread e aproveitar múltiplas threads.
- Eu precisava de mais tipos. Só com TypeScript isso não matava essa sede.
Por que escolhi a linguagem Go?
- O novo backend precisava 1) ser compilado, 2) cuidar da gestão de memória por conta própria e 3) não exigir a instalação de algo como um runtime separado.
- Depois de considerar Rust, Kotlin, Python, PHP e Go, acabei escolhendo Go, que para mim era novidade, mas atendia aos três requisitos. (Desculpa, PHP)
- O que mais me agradou em Go foi a sua simplicidade, e as semelhanças com TypeScript também pesaram bastante na escolha. Acima de tudo, considero que foi uma boa opção em comparação com as alternativas, especialmente em gerenciamento de concorrência e memória.
Como foi usar Go?
- Percebi que Go também prova que não existe linguagem com só vantagens.
if err != nil { }é de fato necessário, mas é realmente muito cansativo. Às vezes sinto falta detry catch finally. - Pode ser um problema do
go-mysql-driver, mas em um ambiente real de desenvolvimento, onde há o gargalo de I/O de banco de dados, ele não se mostrou tão rápido assim. (Veja este post publicado aqui no GeekNews: https://pt.news.hada.io/topic?id=18048) - A aplicação implícita de interfaces ainda me parece um pouco estranha. Será que eles realmente não queriam usar palavras-chave como
implementsouextends? - Foi bom reencontrar ponteiros. Principalmente por não precisar me preocupar com o momento de liberar memória!
- Os vários tipos, as structs simples mas poderosas e os slices são maravilhosos. O melhor é que, como há poucas palavras-chave, dá para aprender e começar a usar rapidamente.
- Poder usar threads leves quase magicamente com a palavra-chave
go...! Estou feliz!
Impressões de trocar o backend de um runtime JS para Go...?
- Fazer esse tipo de coisa uma vez já basta.
- Fiz vários testes ao comparar a parte de I/O de banco de dados, e do ponto de vista de desempenho, sinceramente é difícil sentir uma grande diferença entre um runtime JS e um binário Go. Por exemplo, no caso da biblioteca de imagens
sharp, muito usada em JS, ela também usa a bibliotecalibvips, e não existe aplicação web sem I/O de banco de dados. - Mesmo assim, apesar de ter sofrido bastante, acho que a mudança valeu muito a pena, e pretendo continuar usando apenas Go no backend daqui para frente.
- O uso de memória cai para um nível realmente significativo. Claro, com Rust seria possível otimizar ainda mais, mas considerando o benefício de poder usar GC, esse nível já me deixa plenamente satisfeito.
- A simplicidade da linguagem em si é absurda. Há poucas palavras-chave para decorar, e a maioria dos padrões de uso já é bem definida, então é fácil de aprender. (Claro, usar bem já é outra história.) Gostei muito do fato de haver uma boa variedade de tipos primitivos disponíveis.
- Acima de tudo, o ponto mais satisfatório é que, depois de compilar, se houver apenas o binário, ele simplesmente roda. Não quero mais depender de instalar algo extra para subir o backend e então executar o código por meio disso.
Como usar?
- Infelizmente, o ambiente Windows não é suportado. Basta executar o binário em um ambiente Linux/Mac.
- A biblioteca
libvipsprecisa estar instalada previamente no servidor que você usa. Isso porque o binário utiliza os recursos dessa biblioteca para processar imagens. - Expliquei os detalhes no arquivo
README.md.
Ainda há muito a melhorar, e continuo aguardando as opiniões valiosas de outros desenvolvedores. A ponto de eu me frustrar comigo mesmo por ter ficado tão hesitante no evento GeekNight. Relatos de bugs, sugestões de melhoria ou até opiniões diferentes, tudo é bem-vindo.
Neste ano, dezembro está especialmente pesado, mas ainda assim espero que o novo ano traga um futuro melhor. Obrigado por lerem este texto longo. Por fim, compartilho abaixo o link para as notas de lançamento do TSBOARD v1.0.0.
12 comentários
Vi isso no Damoang.
É um CMS promissor. Obrigado.
Também fiquei surpreso porque há pessoas no Damoang que ainda se lembram de mim. haha Vou me esforçar ainda mais para corresponder às expectativas! 😊
Muito útil!
Embora tarde, agradeço pelo comentário! 😃
Há prós e contras, mas uma vantagem que às vezes sinto é que, sem modificar o código de bibliotecas padrão/externas, dá para usar uma implementação feita por outra pessoa e tratar parte dela como uma
interfaceque eu defini. É comoFunctionalInterfacedo Java, ou como aplicar duck typing a uma linguagem compilada. Por outro lado, se fosse um modelo em queimplements/extendsprecisassem ser declarados obrigatoriamente, para vinculá-la a umainterfacecriada por mim eu teria que implementar um Adapter no meio.Como desvantagem, quando se adiciona/remove/altera métodos em uma
interface, o local onde os erros aparecem acaba sendo diferente em comparação com outras linguagens de tipagem estática, o que é meio incômodo.Ah, entendi! Tinha uma vantagem em que eu nem tinha pensado. Felizmente, acho que eram as mensagens de erro do
gopls? A extensão de Go do VSCode detectava bem o que eu tinha deixado passar ou implementado errado, então eu conseguia encontrar rapidinho. Quando eu me acostumar mais, acho que algum dia também vou conseguir usar melhor. Haha, obrigado pela explicação nos comentários! Feliz Ano-Novo!Parabéns pelo esforço! Eu também vou colocar no servidor de testes! Muito sucesso para você também no Ano-Novo de 2025!
Obrigado! Façam um teste e, se algo não funcionar bem ou se vocês tiverem alguma dúvida, por favor, nos avisem a qualquer momento! Feliz Ano Novo~!
Estou torcendo por vocês~ 👍🏻
Muito obrigado pelo apoio!!! Feliz Ano-Novo~!
Torcendo por vocês!
Obrigado!!! Feliz Ano-Novo!!