Como Estou Aprendendo Kotlin
Alguns dias antes do fim de 2024 eu estava olhando algumas anotações no computador que datavam de 2019. Nessas anotações haviam muitos registros de coisas que eu queria fazer, mas que por um motivo ou outro acabei não fazendo. Reler duas delas me empolgaram: Estudar Kotlin e começar a escrever.
Eu tinha esquecido sobre essa vontade de estudar Kotlin até ver algumas vagas interessantes no LinkedIn que pediam essa linguagem, então quando vi minhas anotações foi muito bom, me deu um "gás"!
Hoje estou começando a fazer os dois (e já estou percebendo que escrever em um blog é mais difícil que aprender uma linguagem de programação nova)!
Como eu aprendo?
Eu nunca tinha pensado sobre isso.
No caso de linguagens de programação e ferramentas, eu gosto sempre de começar pela documentação, mas artigos e vídeos sempre são bons complementos.
Quando é algo grande, como uma linguagem de programação, só ler a documentação não dá. Precisa praticar.
Algumas pessoas gostam de fazer um repositório e ir testando cada parte: sintaxe, declaração de variáveis, chamadas de funções, etc. O famoso "Hello World", mas particularmente eu acho isso muito, muito chato.
Então eu preciso de um projeto.
Se tu pesquisar ideias de projetos para estudar, vai aparecer um monte. Tem até repositórios no github com várias ideias. Um repositório que eu acho interessante é o codecrafters-io/build-your-own-x.
Mas ainda não é o que eu quero. Na prática, qualquer ideia serve, pode ser simples, pode ser complexo, pode até ser chato se precisar, mas como não é algo tão urgente, tentei encontrar algo que eu queria fazer.
A Ideia
Outro dia em dezembro eu estava assistindo um anime. Reassistindo. Era um dos meus animes preferidos chamado Clannad. Eu começava assistindo no computador, mas o cansaço uma hora chegava e eu queria deitar. Como eu estava empolgado, eu queria continuar assistindo o máximo que eu pudesse, então eu assistia no celular até não aguentar mais.
No caso de Clannad era um site que transmitia o anime. Bastava acessar através do navegador e tudo certo, mas comecei a pensar:
"E se eu quisesse assistir no computador E no celular os animes que tenho salvo no computador?"
Era isso!
Estava aí a minha ideia para aprender Kotlin:
Uma aplicação web que vai servir, em um servidor local, os vídeos que eu quiser assistir.
Me inspirei um pouco no jellyfin/jellyfin. Minha intenção não é fazer algo tão completo quanto ele, mas a ideia de um servidor local para eu assistir os meus arquivos onde quiser é parecida.
Ferramentas
Meu início com o Kotlin não foi muito agradável. Eu uso Windows como host e minhas instalações de trabalho ficam no WSL2 com Arch Linux.
Tudo o que eu preciso está lá e daí não preciso misturar coisas de trabalho com o Windows que serve mais para entretenimento.
No caso do Kotlin, as extensões para o VSCode não estão muito atualizadas. Falta manutenção. Para não brigar com o editor de código, me rendi a tentar uma IDE, no caso o IntelliJ IDEA Community.
Primeiro tentei instalar a IDE direto no WSL2, mas por algum motivo esperava não dar certo por causa do Xorg e não deu, o que é muito estranho, pois eu já consegui abrir o chromium e o firefox direto do WSL e funcionava bem (e eu não sabia o porquê funcionava).
Na primeira tentativa, frustrada, já recebi uma mensagem de erro relativo a não conseguir se conectar a $DISPLAY. Pensei: "Não há suporte para aplicações com interface gráfica no WSL, mas isso não faz sentido".
Parti então para outra alternativa que eu sabia que era possível quando estava pesquisando sobre Kotlin: usar o IntelliJ IDEA no Windows, mas se conectar com o sistema de arquivos do WSL através de \\wsl.localhost.
Instalei o IDEA no Windows e logo ao iniciar o programa ele já sugere que tu importe as configurações do VSCode, o que foi excelente, ele até identificou meu diretório de projetos no WSL. Abri o projeto doragon na IDE e tive mais um problema.
O syntax highlight não estava funcionando. Dei uma pesquisada no que poderia ser, instalei um tema parecido com o que uso no VSCode e nada do syntax highlight funcionar.
Até que percebi que a IDE estava demorando para carregar o projeto, indexar arquivos, etc. (aquela barrinha que fica carregando no canto direito-inferior da janela). Deu tempo de eu fazer altas pesquisas e meu esqueleto de projeto ainda não tinha carregado. Eu já esperava que seria lento. Trabalhar com a conexão ao sistema de arquivos do WSL através dessa conexão via \\wsl.localhost é lento, mas não sabia que seria TÃO lento.
Depois de terminar de indexar os arquivos o IDEA funcionou normalmente, mas aquela lentidão era inviável. Pensei: "Não é possível que as pessoas trabalhem assim. Tem que ter um jeito".
Minha instalação do Arch Linux no WSL2 é antiga e eu não acompanhei direito as evoluções que aconteciam no sistema.
Comecei a pesquisar uma forma de resolver essa lentidão. Minha ideia inicial era instalar o Xorg no WSL e um cliente de X11 no Windows, assim eu conseguiria me "conectar a interface gráfica" do WSL. Eu não sabia como fazer isso, só sabia que era possível.
Durante a pesquisa descobri que a Microsoft tinha adicionado novos recursos ao WSL e um deles era o WSLg. Este recurso basicamente instala tudo que tu precisa para executar uma aplicação gráfica de dentro do WSL. Basta instalar e abrir o programa e tudo certo.
Mas comigo não funcionava de jeito nenhum. Sempre que tentava abrir o Intellij IDEA aparecia o erro de não conseguir se conectar a $DISPLAY. Resolvi testar outra aplicação, o GIMP, para ver se era um problema isolado com o IDEA e deu o mesmo problema. Testei com o Firefox também e deu erro.
Vamos pesquisar mais. Se está rodando no computador dos outros tem que rodar no meu computador também!
Com o erro mostrado no GIMP consegui encontrar este link: Diagnosing "cannot open display" type issues with WSLg.
Fiz alguns testes como demonstrado no link e funcionou. Embora o arquivo /tmp/.X11-unix existisse no meu sistema, ele não era um symlink. Quando fazia ls /tmp/.X11-unix não aparecia X0. Removi o arquivo, criei o symlink e testei com ls de novo e apareceu X0. Executei o IntelliJ IDEA e abriu! GIMP e Firefox também!
Problema resolvido. Segundo esta issue no github tem algo a ver com o systemd. O symlink para o socket do X11 é perdido durante a inicialização do WSL. Enquanto eu lia como instalar o IntelliJ IDEA eu descobri que dava para ativar o systemd no WSL e assim o fiz, pois precisava para instalar o snap. Por isso o Chromium e o Firefox funcionavam, na época eu não tinha ativado o systemd, então o WSLg estava funcionando normalmente!
O Projeto: vv-z84/doragon
Depois de resolver os problemas com o ambiente de desenvolvimento comecei a pensar na implementação da ideia.
A Ideia É Simples™.
Como escrevi antes, é uma aplicação que vai servir os arquivos que tenho no computador. Dá para fazer isso de várias formas. Inicialmente pensei em fazer a aplicação com uma página para eu cadastrar os vídeos que eu quero assistir, outra para listar os vídeos cadastrados e outra onde apresento o video escolhido.
Simples, porém chato. Uma temporada de um anime pode ter 20 episódios. Poderia cadastrar um por um ou fazer o upload em massa. O upload ia bater na aplicação spring, o servidor ia ficar ocupado enquanto faz os uploads. Tudo bem para uma aplicação que vai rodar localmente, provavelmente terá somente eu de usuário. Funciona? Funciona, mas vamos melhorar essa ideia.
E se minha aplicação servisse os arquivos que estão em um diretório? Um "public/static". Assim eu não preciso ficar cadastrando. Basta copiar todos os arquivos para dentro desse diretório e a aplicação tem então duas páginas: uma para a listagem do conteúdo do diretório público e outra para apresentar o vídeo escolhido. Dessa forma também resolvemos o problema da aplicação ficando ocupada durante o upload e a infraestrutura fica mais simples, sem necessidade de um banco de dados. Legal, acredito que resolva o problema, mas dá para deixar mais interessante.
Como é um projeto de estudo também, nós podemos experimentar. Depois de pensar bastante eu cheguei na seguinte ideia:
Vou ter um diretório onde coloco os arquivos que quero assitir. Um programa ficará ouvindo eventos nesse diretório. Quando um arquivo é escrito nesse diretório o programa escuta um evento de escrita e processa esse evento enviando informações para uma fila em forma de Task (tarefa).
Outro programa ficará observando essa fila e processando as tarefas que forem entrando. Quero testar mais de uma instância desse programa que vamos chamar de worker. Dois workers pelo menos para processar as tarefas da fila.
Uma tarefa ser processada significa que o worker adicionou algumas informações do vídeo em uma tabela e fez o upload do video em um Object Storage.
A aplicação só precisa se preocupar em listar os registros do banco de dados. Uma página com a lista de vídeos e uma com a apresentação do vídeo.
Por fim, a aplicação será uma API, então preciso implementar também um client para essa API que a princípio será uma página HTML simples.
O programa que ouve as escritas no diretório pode ser uma console application. Os workers também. A API será feita com Spring e as filas serão gerenciadas pelo RabbitMQ. O Object Storage será o minio e como banco de dados usarei Postgres.
A infraestrutura será gerenciada em containers via docker-compose.
Com essa ideia dá para aprender e exercitar muitas coisas: Kotlin e Java, o framework Spring, trabalho assíncrono com filas e workers, Docker e Docker Compose, fora alguns problemas e dúvidas que podem surgir durante o desenvolvimento como:
O que fazer se o programa que está escutando os diretórios crashar? Como executar ele automaticamente caso isso aconteça? Como lidar com os arquivos que ficaram no diretório já que não vai acontecer o evento de escrita novamente para o programa enviar para a fila?
A mesma coisa para os workers que estão processando os itens da fila. E se der crash durante um upload para o minio? Como fazer para não perder a tarefa que estava na fila?
Acho que vai ser uma brincadeira boa!
Como não é o intuito deste artigo ser um tutorial ou algo do tipo, não pretendo descrever neste momento cada parte do desenvolvimento do projeto. Caso tenha interesse, tu pode acompanhar o desenvolvimento deste projeto em vv-z84/doragon.
Por hoje é isso! Até logo.