[{"content":"Comprei uma ASUS ProArt X870E-Creator WiFi e o Wi-Fi funcionou de primeira. O Bluetooth, não. Nunca apareceu adaptador nenhum, e o pior: o dispositivo simplesmente não estava no lsusb. Nem travado, nem com erro — ausente.\nMinha primeira hipótese foi a mais óbvia, e estava certa pela metade: o firmware de Bluetooth desse chip não vem no linux-firmware. O que eu não imaginava é que o firmware faltando não é o que quebra o hardware. O que quebra é o que o driver faz a respeito disso.\nNeste artigo vou reconstruir a investigação inteira, incluindo os dois momentos em que eu conclui a coisa errada com confiança total. Acho que essas partes são mais úteis que a solução.\nPlaca-mãe ASUS ProArt X870E-Creator WiFi rev 2 BIOS 2402 Sistema Bazzite (Fedora 44 Atomic) Kernel 7.2.3-ogc3.1.fc44.x86_64 Bluetooth MediaTek MT6639, USB 0489:e13a Wi-Fi MediaTek MT7927, PCIe 14c3:7927 O sintoma: um adaptador que não existe Nenhum adaptador. O bluetoothctl show trava sem imprimir nada, porque o bluetoothd fica esperando um controlador que nunca vai aparecer. E o dmesg não tinha absolutamente nenhuma mensagem do subsistema Bluetooth — nem sucesso, nem falha de firmware, nem erro de USB. Silêncio total.\nSilêncio total é um resultado estranho. Se o firmware faltasse, eu deveria ver o driver reclamando. Se o dispositivo estivesse com defeito, eu deveria ver o USB reclamando. Não ver nada significa que o kernel nem tentou.\nO falso negativo que me custou uma rodada inteira Aqui está o primeiro erro, e ele é constrangedor de tão simples.\ndmesg | grep -iE \u0026#39;btusb|bluetooth: hci\u0026#39; Isso voltava vazio. Eu li \u0026ldquo;vazio\u0026rdquo; como \u0026ldquo;não há mensagens de Bluetooth\u0026rdquo;. Errado. O que estava acontecendo é que o kernel.dmesg_restrict=1 faz o dmesg sem root retornar zero linhas de qualquer tipo. Não havia mensagem nenhuma pra filtrar — de Bluetooth, de USB, de nada.\n$ dmesg | wc -l 0 $ sysctl -n kernel.dmesg_restrict 1 Um grep vazio em cima de uma entrada vazia parece exatamente igual a um grep vazio em cima de mil linhas. A lição prática: use journalctl -k, que funciona sem sudo e te dá o log de verdade.\n$ journalctl -k -b 0 --no-pager | wc -l 1893 Mil oitocentas e noventa e três linhas que eu vinha ignorando. E dentro delas estava tudo.\nO dispositivo não sumiu — ele travou Com o log de verdade em mãos, o quadro mudou completamente. O dispositivo está lá, na porta 1-6, vizinha do controlador de LED da placa. Ele é detectado eletricamente. Ele simplesmente não responde a nada.\nusb 1-6: new high-speed USB device number 4 using xhci_hcd usb 1-6: device descriptor read/64, error -110 usb 1-6: device descriptor read/64, error -110 usb 1-6: new high-speed USB device number 5 using xhci_hcd usb 1-6: device descriptor read/64, error -110 usb 1-6: device descriptor read/64, error -110 usb usb1-port6: attempt power cycle usb 1-6: new high-speed USB device number 6 using xhci_hcd usb 1-6: Device not responding to setup address. usb 1-6: device not accepting address 6, error -71 usb 1-6: new high-speed USB device number 7 using xhci_hcd usb 1-6: Device not responding to setup address. usb 1-6: device not accepting address 7, error -71 usb usb1-port6: unable to enumerate USB device Traduzindo: -110 é timeout, -71 é erro de protocolo. O hub vê que tem alguma coisa plugada, tenta ler o descritor do dispositivo, não recebe resposta, corta e religa a energia da porta, tenta de novo, desiste. Quatro tentativas, sessenta e três segundos, nada.\nIsso também explica por que o btusb não estava carregado, e por que isso não era o problema. O udev carrega o módulo quando aparece um modalias que casa com ele. Como nada enumerou, não existe modalias, então o módulo não carrega. Carregar na mão funciona sem erro nenhum e não cria dispositivo HCI algum:\n$ sudo modprobe btusb \u0026amp;\u0026amp; ls /sys/class/bluetooth/ # (vazio) A pilha de software está impecável. O hardware é que não aparece.\nA causa: o btusb tenta pra sempre O journal do Bazzite guarda os boots anteriores, e é aí que a coisa fica interessante. Varri todos os boots registrados procurando pelo dispositivo, e em dois deles ele funcionou — enumerou normalmente. Fui olhar o que tinha acontecido:\n[ 3.068951] usb 1-6: New USB device found, idVendor=0489, idProduct=e13a [ 3.069092] usb 1-6: Product: Wireless_Device [ 8.221018] usbcore: registered new interface driver btusb [ 8.233139] Bluetooth: hci0: Failed to load firmware file (-2) [ 8.233145] Bluetooth: hci0: Failed to set up firmware (-2) [ 8.564037] usb 1-6: reset high-speed USB device number 4 using xhci_hcd [ 8.817354] Bluetooth: hci0: Failed to load firmware file (-2) [ 9.147127] usb 1-6: reset high-speed USB device number 4 using xhci_hcd [ 9.402354] Bluetooth: hci0: Failed to load firmware file (-2) [ 9.727020] usb 1-6: reset high-speed USB device number 4 using xhci_hcd Achou o padrão? O firmware falha com -2 (ENOENT, arquivo não encontrado), e o btusb reseta o dispositivo por USB e tenta de novo. Aí falha de novo, reseta de novo, tenta de novo. A cada 0,58 segundos. Sem backoff, sem limite de tentativas, sem desistir nunca.\nNaquele boot isso rodou por 13 minutos até eu desligar a máquina. Foram 1335 resets.\nE é isso que trava o chip. A cadeia inteira é assim:\nPartida a frio limpa: o controlador enumera normalmente, uns 3 segundos depois do boot. O btusb faz bind aos ~8 segundos, cria o hci0, pede o firmware. O arquivo não existe. Retorna -2. O btusb reseta o dispositivo e tenta de novo. E de novo. Indefinidamente. Depois de algumas centenas de resets, o firmware do controlador trava. A partir daí, a porta detecta o dispositivo mas ele não responde mais nada. Isso sobrevive a reboots, porque o trilho de energia de standby mantém o chip alimentado. O ponto 7 é o que torna isso cruel. Você reinicia, não resolve. Reinstala o sistema, não resolve. O chip continua travado porque nunca foi desenergizado de verdade.\nAs contas batem O que me convenceu de que essa era mesmo a causa, e não uma coincidência, foi contar. Se o loop de reset é consequência da falha de firmware, os dois números têm que ser idênticos:\nBoot Resets da porta 1-6 Falhas de firmware -8 398 398 -1 1335 1335 Batem exatamente. Um reset para cada falha, nos dois boots.\nE o padrão de reincidência entre boots conta o resto da história:\nBoot Porta 1-6 Leitura -8 enumerou partida limpa, 398 resets, trava -7 a -3 sem eventos cinco boots mortos, consequência do -8 -2 falha na enumeração travado -1 enumerou destravado por corte de energia, 1335 resets, trava de novo 0 falha na enumeração travado Dois ciclos completos. Toda vez que eu destravava o chip cortando energia, ele voltava, entrava no loop, e travava de novo. Eu estava reproduzindo o problema sem saber.\nPara destravar, o caminho é cortar a energia de verdade: habilitar ErP em S4+S5 na BIOS e usar poweroff (não reboot, que nunca corta o standby), ou tirar da tomada por uns 10 segundos.\nAh, e o boot lento era o mesmo bug Eu tinha uma segunda queixa que achava não ter relação: o boot estava demorando quase dois minutos. Tinha.\nO systemd-udev-settle.service fica na raiz da cadeia crítica do boot — tudo espera por ele. E as retentativas de enumeração na porta 1-6 mantêm o udev ocupado:\nEstado da porta 1-6 Boots udev-settle dispositivo ausente -7 a -3 8,6 – 9,7 s dispositivo travado -2, 0 67,8 s Uns 59 segundos de penalidade, batendo com a janela de 63 segundos das retentativas. Depois que o controlador subiu direito, o boot foi de 1min52s para 41s. Dois sintomas, um bug só.\nOnde colocar firmware quando /usr é read-only O Bazzite é um sistema imutável: /usr é somente-leitura, então não dá pra simplesmente jogar o arquivo em /usr/lib/firmware. A rota padrão é usar /var/lib/firmware e apontar o kernel pra lá com um parâmetro de boot:\nsudo install -Dm644 BT_RAM_CODE_MT6639_2_1_hdr.bin \\ /var/lib/firmware/mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin sudo rpm-ostree kargs --append=firmware_class.path=/var/lib/firmware Fiz isso, reiniciei, e o Bluetooth funcionou. Fim do artigo, certo?\nNão. Fui conferir o log e o firmware tinha falhado com -2 de novo — e mesmo assim o dispositivo subiu. Isso não fazia sentido nenhum, e a explicação é a parte mais interessante de tudo.\nA corrida que eu ganhei por 174 milissegundos Em sistemas ostree, o /var é um subvolume montado por uma unit do systemd depois do switch-root. E o btusb faz probe exatamente dentro dessa janela.\nTempo Evento 7,294 s switch-root 8,677 s btusb registra o interface driver 8,688 s primeira tentativa de firmware falha, -2 9,021 s btusb reseta o dispositivo e reagenda 9,235 s var.mount conclui 9,409 s o retry encontra o firmware 28,758 s Device setup in 19036182 usecs 28,930 s AOSP extensions version v1.00 Ou seja: funcionou pelo motivo errado. A primeira iteração do loop de reset — o mesmo loop que trava o chip — foi justamente o que salvou, porque o /var montou no meio dela. A margem foi de 174 milissegundos.\nIsso é sorte reproduzível, não garantia. Se o retry caísse 200 ms mais cedo, o loop começaria e o chip travaria. Ainda por cima, tem um detalhe cruel: existe um /var stub não-vazio embaixo do ponto de montagem no deployment, então a busca falha em silêncio em vez de dar erro de diretório ausente.\nA correção de verdade A solução é colocar o firmware num lugar que já esteja legível no switch-root. O /etc serve: ele é um bind mount do próprio subvolume do deployment, montado pelo ostree-prepare-root ainda dentro do initrd. Está disponível aos 7,294 s, mais de um segundo antes do btusb fazer probe.\nsudo install -Dm644 BT_RAM_CODE_MT6639_2_1_hdr.bin \\ /etc/firmware/mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin sudo rpm-ostree kargs \\ --replace=firmware_class.path=/var/lib/firmware=/etc/firmware Detalhe simpático: o SELinux rotula o arquivo como cpucontrol_conf_t, porque /etc/firmware já é um caminho que a policy conhece (usado para microcode de CPU). E não bloqueia nada — a policy carregada nem define a permissão firmware_load.\nPara validar depois do reboot, os dois números têm que dar zero:\njournalctl -k -b 0 | grep -c \u0026#39;Failed to load firmware file\u0026#39; journalctl -k -b 0 | grep -c \u0026#39;reset high-speed USB device\u0026#39; A armadilha do /etc staged — quase desisti aqui Esse foi o segundo momento em que eu conclui a coisa errada com confiança total, e valeu um susto.\nDepois do rpm-ostree kargs, fui conferir o deployment novo antes de reiniciar. O /etc/firmware não estava lá. E o deployment é read-only, então nem dava pra colocar na mão.\nIsso parecia fatal. Com o parâmetro de boot apontando só pro /etc/firmware, um arquivo ausente significa que a primeira tentativa e o retry falham, já que o /var saiu do caminho de busca. Ou seja: pior do que não ter mexido em nada.\nAntes de reverter, resolvi comparar as duas árvores de /etc. A do deployment novo estava sem 23 itens que a atual tinha:\nbazzite cardwire cni crypttab firmware fstab group- gshadow- hostname iwd locale.conf localtime passwd- sddm.conf.d shadow- subgid- subuid- vconsole.conf Olha o fstab ali no meio.\nÉ isso que resolve a questão. Se a finalização não fizesse o merge do /etc, nenhum sistema ostree conseguiria bootar depois de um upgrade, porque ficaria sem fstab. Logo, o /etc de um deployment staged é o pristine do commit novo, e o merge de 3 vias é diferido para o ostree admin finalize-staged, que roda no shutdown.\nOu seja: inspecionar um /etc staged sempre vai parecer que suas modificações locais sumiram. É o esperado, não um defeito. Meu arquivo ia ser carregado junto com o fstab e o hostname, e foi.\nO que me tirou do buraco não foi conhecimento prévio de ostree, foi procurar uma evidência que decidisse a questão em vez de apostar num palpite.\nDe onde vem esse firmware, afinal O blob de Bluetooth não está no linux-firmware. O MR !946 foi fechado porque o projeto só aceita blobs submetidos por quem detém os direitos — precisa vir da própria MediaTek. O de Wi-Fi entrou pelo MR !1055, e é exatamente por isso que a metade Wi-Fi do chip funciona de fábrica e a metade Bluetooth não.\nDá pra extrair dos pacotes de driver Windows da ASUS com o extract_firmware.py do projeto jetm/mediatek-mt7927-dkms. Extraí de dois pacotes diferentes, de forma independente, e os arquivos saem byte a byte idênticos:\nPacote Container Tamanho Bluetooth V1.1147.0.610 mtkbt_v2.dat 571349 B Wi-Fi V5706054 mtkwlan.dat 571349 B sha256 2135f2c4220cfa6e8eb9fdf430517098c13b862a95844bbff0153240a768efa8 caminho mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin build 20260611041233 Duas observações que economizam tempo. O caminho é mediatek/mt7927/, e não mediatek/mt6639/ — confirme direto nas strings do módulo com modinfo -F firmware btmtk em vez de deduzir da mensagem de erro, porque essa convenção já mudou entre versões do kernel. E circula por aí um hash 669c5c99... com uns 688 KB que não reproduziu aqui em nenhum dos dois pacotes; duas extrações independentes concordando pesam mais que um número solto de comunidade.\nO que não fazer — leia antes de replicar Não rode modprobe -r btusb. O firmware do MT6639 trava durante reload de módulo e o dispositivo some do lsusb de forma persistente. Foi assim que essa história começou. Prefira reboot. Não instale arquivos WIFI_*.bin no caminho de firmware. O linux-firmware já traz os corretos, comprimidos, em /usr/lib/firmware/mediatek/mt7927/. Uma cópia solta sombra silenciosamente o blob mais novo e quebra o Wi-Fi que hoje funciona. Só o arquivo de Bluetooth deve ser instalado. Não espere que reboot destrave o controlador. O trilho de standby mantém ele energizado. Só corte real de energia resolve. Não deixe o loop rodar depois de ver a falha de firmware. Cada ciclo de reset arrisca travar o chip de novo e custa mais um corte de energia. Desligue assim que aparecer Failed to load firmware file (-2). O que deveria mudar no kernel Um arquivo de firmware que não existe vai continuar não existindo na próxima tentativa. Retentar o mesmo pedido milhares de vezes não tem como dar certo — e aqui faz mal ativamente, porque empurra o controlador para um estado que sobrevive a reboots e exige intervenção física.\nUm limite de tentativas, ou um backoff, ou simplesmente não retentar em -2 quando a tentativa anterior falhou pelo mesmo motivo, transformaria isso de um dispositivo travado numa linha de log dizendo que o firmware está faltando. Vou levar isso pra linux-bluetooth.\nConclusão O que eu tiro dessa investigação não é o comando final, que cabe em duas linhas. São duas outras coisas.\nA primeira é que ausência de evidência não é evidência de ausência, e ferramenta silenciosa mente. Um grep vazio me convenceu por um bom tempo de que não havia log, quando na verdade não havia permissão. Vale sempre confirmar que a ferramenta está te devolvendo dados antes de interpretar o silêncio dela.\nA segunda é que o segundo susto — o /etc staged aparentemente vazio — se resolveu porque eu procurei uma evidência que decidisse a questão em vez de confiar no que eu achava que o ostree fazia. O fstab naquela lista valia mais que qualquer certeza minha sobre o funcionamento do sistema.\nE, no fim, o firmware faltando era mesmo o problema. Só que ele não quebrava nada sozinho: quem quebrava era o driver, tentando resolver com afinco infinito uma coisa que não tinha como ser resolvida daquele jeito.\nSe você tem esse chip e caiu aqui procurando por que seu Bluetooth não funciona, espero que este artigo economize os dias que ele me custou. Qualquer dúvida ou correção, é só me chamar.\nAté a próxima!\n","permalink":"https://blog.batcode.io/posts/mt6639-bluetooth-loop-de-reset/","summary":"\u003cp\u003eComprei uma ASUS ProArt X870E-Creator WiFi e o Wi-Fi funcionou de primeira. O Bluetooth, não. Nunca apareceu adaptador nenhum, e o pior: o dispositivo simplesmente não estava no \u003ccode\u003elsusb\u003c/code\u003e. Nem travado, nem com erro — ausente.\u003c/p\u003e\n\u003cp\u003eMinha primeira hipótese foi a mais óbvia, e estava certa pela metade: o firmware de Bluetooth desse chip não vem no \u003ccode\u003elinux-firmware\u003c/code\u003e. O que eu não imaginava é que o firmware faltando não é o que quebra o hardware. O que quebra é o que o driver faz a respeito disso.\u003c/p\u003e","title":"Bluetooth fantasma no Linux: como o btusb trava o MediaTek MT6639 tentando carregar um firmware que não existe."},{"content":"Baseado no artigo original The Freedom of Value de Gigi, esta tradução e adaptação seguem os termos disponibilizados em dergigi.com/translations, sob a licença Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0).\nCom a palavra, o autor:\nA internet tem um problema. Poucas pessoas sabem que esse problema existe, mas, veja bem, essa é a natureza dos problemas sérios e não óbvios: eles permanecem invisíveis — até que deixam de ser. O problema da internet é que a informação quer ser livre. E, se algo quer ser livre no sentido de liberdade, com tempo suficiente, também acabará sendo livre no sentido de \u0026ldquo;gratuito\u0026rdquo;.\nDeixe-me explicar.\nEnvenenando o Ar Consumimos uma quantidade incalculável de dados todos os dias. A cada segundo, de cada minuto, bits e bytes percorrem os tubos invisíveis que todos conhecemos e amamos: a internet. A gente se acostumou com isso — e também se acostumou com o modelo atual de monetização, junto com todos os problemas que ele traz. Raramente paramos para pensar nesse mundo estranho de zeros e uns. O quão incrível ele é, mas ao mesmo tempo tão distante da nossa compreensão. Já mudou completamente nossas vidas — e vai continuar mudando nosso futuro. Mas de onde vêm esses zeros e uns? O que faz tudo isso funcionar? E, mais importante: quem está pagando por isso?\nEsses bits e bytes que viajam pelos nossos cabos de fibra ótica são tão invisíveis quanto o ar que respiramos. Aliás, essa é uma boa metáfora. Enquanto conseguimos respirar sem dificuldade, não precisamos analisar cada molécula que entra nos nossos pulmões. Do mesmo jeito, enquanto conseguimos criar e consumir conteúdo digital sem muitos problemas, não sentimos a necessidade de questionar tudo o que mantém a economia da atenção funcionando.\nEconomia da atenção. Que nome apropriado. Como todos deveríamos saber, o que consumimos na internet não é de graça — estamos pagando caro por isso: com nossa atenção, entre outras coisas.\nPagando com Atenção No mundo acelerado de hoje, para maximizar os lucros, é preciso maximizar a atenção. Mas é um tipo de atenção peculiar — e superficial. Não é aquela atenção focada que o pensamento profundo ou uma conversa significativa exigiriam. Acredito que é justamente por isso — ao menos em parte — que tanta coisa parece quebrada: por que nosso discurso social está tão fragmentado, nossa política tão polarizada, nós tão paralisados — e nossas análises, tão rasas quanto nossos desejos.\nA economia da atenção nos dividiu perfeitamente em bolhas de verdades pessoais. Ironia das ironias: a única “verdade” que realmente importa na economia da atenção é como manter o maior número possível de pessoas, no maior nível possível de indignação, pelo maior tempo possível. E tudo isso mantendo os participantes sem perceber que estão **presos em uma prisão algorítmica construída pelas próprias escolhas que fizeram.\nVocê é o Produto O ditado “se algo é de graça, é porque você é o produto” nunca é repetido o suficiente.\nPor algum motivo, criamos a expectativa de que quase tudo na internet deve ser “gratuito”. Mas é claro que não existe almoço grátis. No caso dos serviços online, seus dados são colhidos e vendidos para o maior lance — normalmente, uma empresa de publicidade… ou uma agência governamental. Ou as duas.\nNão só todas as grandes empresas de dados espionam você, como também usam padrões obscuros (dark patterns) e práticas antiéticas para extrair até a última gota de informação sobre você.\nNão importa se o nome da armadilha é Facebook Pixel, Google Analytics ou qualquer outra coisa — você está sendo rastreado, monitorado e catalogado. O que você vê, por quanto tempo, em que horários, com que frequência e o que vai ver a seguir… tudo isso é cuidadosamente orquestrado por algoritmos otimizados para gerar lucro — lucro para a plataforma, não para você.\nClaro, a ideia vendida é que todo mundo sai ganhando: usuários, criadores, anunciantes e as próprias plataformas. Mas o “ambiente evolutivo” criado por esse sistema de incentivos acaba favorecendo conteúdo superficial, chamativo e sensacionalista.\nAté o momento desta escrita — bloco 716.025 — a expressão máxima desse ambiente é o TikTok, uma verdadeira máquina de dopamina em formato de vídeo, que serve a você o equivalente visual de heroína misturada com crack. Drogas pesadas para a mente, sob medida para seus gostos mais específicos. Um aplicativo verdadeiramente amaldiçoado.\nInfelizmente, a maioria das plataformas desse tipo não é diferente em essência — apenas em grau.\nOpinião Permitida “Não é tão ruim assim”, dizemos para nós mesmos. “Olha quanta informação útil!” — exclamamos, enquanto rolamos sem parar nossos feeds, alimentando sem querer a máquina que, em troca, nos alimenta com doses de dopamina.\nMas não se engane: as empresas por trás disso tudo não estão no negócio de nos oferecer informação útil (ou verdadeira). Elas estão no negócio de nos enganar para que continuemos alimentando a máquina.\nComo poderia ser diferente? Você é o que rastreia. Você se torna aquilo para o qual otimiza. Do ponto de vista da plataforma, isso significa: cliques — não qualidade. No início, maximizar cliques e tempo de visualização pode até parecer algo inofensivo. Afinal, é preciso gerar receita para sobreviver. “É só um anúncio. Qual o problema?”\nInfelizmente, os problemas são invisíveis no começo. Assim como o câncer é invisível para quem acabou de fumar o primeiro cigarro, ou a cirrose para quem bebeu o primeiro gole, a censura, o banimento, a polarização e a manipulação da opinião pública também são invisíveis para o usuário-produtor (prosumer) que acabou de ver seu primeiro anúncio num ecossistema fechado.\nE provavelmente podemos concordar: já passamos da fase inicial desse jogo. Hoje, censura é regra, banimento é aplaudido, polarização está em níveis históricos, e a opinião pública é manipulada — manual e algorítmicamente — como nunca antes.\nO consenso atual parece ser: você é burro demais para saber o que é bom pra você. Sua opinião é absurda demais para ser expressa em público. E o pior: essa opinião nem deveria ser sua em primeiro lugar.\n“Aqui está o motivo de você estar errado.” “Aqui está uma fonte que aponta para uma opinião permitida.” “Aqui estão alguns especialistas que concordam conosco.” “Nossos algoritmos inteligentes e prestativos já pensaram por você — e eles nunca erram. Nem os especialistas.” Esse é o mundo em que já estamos vivendo.\nVocê não pode falar livremente. Você não pode pensar livremente. Você não pode se expressar livremente.\nSua foto é ofensiva? Então precisa ser removida. Seu meme chegou perto demais da verdade, ou foi engraçado “demais”? Então você vai pra cadeia do Twitter por uma ou duas semanas. Você disse algo com que “nós” não concordamos? Então será banido para sempre — mesmo que você seja o presidente em exercício, veja bem. Você falou a “palavra errada” num vídeo, ou tocou uma música com direitos autorais no fundo? Então vamos cortar sua renda. Você postou uma foto sem máscara? Então vamos te banir e te denunciar às autoridades.\nO simples fato de que tudo isso já não é mais ficção científica distópica deveria ser motivo de preocupação para todos nós.\nRemovidos do ciberespaço apenas por querer respirar em liberdade. Tempos estranhos.\nPressão Evolutiva Como chegamos até aqui?\nSe eu tivesse que dar uma resposta curta, seria a seguinte: saímos de protocolos e passamos a viver em plataformas — e plataformas só são tão boas quanto os incentivos que as movem.\nA estrutura de incentivos das plataformas que habitamos funciona como um ambiente evolutivo que determina quem sobrevive. Tudo que quiser continuar existindo precisa se alinhar a esse ambiente.\nClaro, isso não vale só para o mundo digital — é verdade em qualquer área de negócio. Pegue as revistas impressas, por exemplo. Por razões profundamente humanas e evolutivas, se sua revista não tiver um belo rosto feminino na capa, ela vai vender menos do que aquelas que têm. Logo, não vai conseguir “se replicar” e, consequentemente, vai morrer.\nDa mesma forma, se seu portal de notícias online não gerar receita suficiente com anúncios, ele também não vai se sustentar — e vai desaparecer. É por isso que toda revista tem um rosto bonito na capa. E é por isso que todo site de notícias baseado em anúncios acaba virando clickbait.\n“Um desses rostos não é como os outros.” Da mesma forma, é por isso que os mecanismos de recomendação baseados em feed acabam se transformando em caça-níqueis para os seus receptores de dopamina.\nQuanto mais tempo você ficar colado na tela, mais anúncios vai ver, mais receita será gerada para a plataforma.\nÉ também por isso que a maioria dos canais no YouTube vira um festival de vídeos de 7 a 15 minutos, com thumbnails mostrando alguém com a cara de quem acabou de pisar em um LEGO. Curtos o suficiente pra te convencer a clicar, longos o suficiente pra te fazer esquecer o que queria assistir em primeiro lugar.\nComo ratos pressionando botões em caixas de Skinner hiper personalizadas, somos condicionados em ciclos de vício para maximizar o lucro dos acionistas.\nMaximizando Lucros Plataformas são empresas, e empresas são incentivadas a maximizar os lucros dos seus acionistas. Não há nada de errado com o lucro — e também nada de errado com os acionistas.\nNo entanto, acredito que a revolução da informação em que estamos inseridos dividiu o ambiente evolutivo em dois. Vamos chamar esses dois ambientes de “amplo” e “estreito”.\nPara maximizar lucros por meio de publicidade ampla, é preciso minimizar controvérsias e opiniões extremas. Ou seja, ao tentar agradar ao denominador comum mais baixo, política e censura entram em cena automaticamente.\nPor outro lado, quando os lucros vêm de publicidade segmentada e altamente direcionada, o caminho se inverte: é necessário aumentar ao máximo a controvérsia e as opiniões extremas. Só de mostrar conteúdos diferentes para grupos diferentes, já se está amplificando a polarização e fragmentação constantemente.\nCoesão de Massa vs. Divisão Algorítmica. Pode até parecer que estamos falando de TV a cabo vs. feed algorítmico de notícias, mas, na prática, são apenas duas estratégias diferentes com o mesmo objetivo: manter o máximo de pessoas coladas na tela para que vejam o máximo possível de anúncios.\nA primeira opção age como um sedativo, a segunda como um estimulante.\nÉ verdade, essa caracterização pode parecer exagerada — mas o problema continua sendo o mesmo: se não estamos pagando diretamente por algo, estamos pagando por ele de outro jeito. Sempre.\nO ponto central é este: plataformas de liberdade de expressão não podem existir. Apenas protocolos de liberdade de expressão podem.\nSe alguém pode controlar o que está sendo dito, então alguém vai controlar o que está sendo dito. Se for possível monitorar, filtrar e censurar conteúdo, então isso será feito — inevitavelmente.\nToda plataforma irá se deparar com esse dilema, não importa quão puras sejam suas intenções.\nMesmo que no início você se posicione como uma “plataforma da liberdade de expressão”, mais cedo ou mais tarde, será forçado a intervir e censurar.\nAfinal, se o Estado pode te esmagar por causa do conteúdo que você hospeda ou transmite… o Estado vai te esmagar por causa do conteúdo que você hospeda ou transmite.\nAutocensura No entanto, muito antes da censura estatal mostrar sua face horrenda, o efeito paralisante da autocensura já será sentido.\nSe outras pessoas são banidas ou desmonetizadas por expressarem certas opiniões, a maioria das pessoas vai pensar duas vezes antes de dizer o mesmo. Conscientemente ou não, vamos aos poucos silenciando a nós mesmos.\nE no caso da autocensura, a publicidade também tem seu papel.\nAfinal, você não morderia a mão que te alimenta, certo?\nNo pior dos cenários, anunciantes e executivos vão dizer diretamente o que pode ser dito e o que é proibido. Eles vão te mostrar quais opiniões estão dentro da “janela de Overton” — e quais estão fora dela.\nE mesmo que eles não digam nada, você vai tentar adivinhar — e ajustar seu discurso por conta própria.\nUm Problema e um Paradoxo Voltando ao problema original: por que não conseguimos vender informação como se fosse um bem comum? Por que a abordagem mais simples — colocar o conteúdo atrás de um paywall — costuma dar tão errado?\nAcredito que isso acontece por dois motivos, que chamarei de “problema do MTX” e “paradoxo do DRM”.\nO Problema do MTX MTX é a abreviação de \u0026ldquo;transação mental\u0026rdquo;, e se refere ao custo psicológico inevitável envolvido em toda transação, por menor que seja.\nToda vez que você bate num paywall, precisa tomar uma decisão consciente: “Será que vale a pena pagar por isso?”\nComo Nick Szabo argumenta de forma convincente, na maioria dos casos — especialmente quando o valor é muito pequeno — a resposta será não. E não por uma razão técnica, mas por motivos psicológicos: o simples esforço mental de julgar se aquela microtransação vale ou não a pena já é cansativo demais.\nSe você precisa pensar sobre uma microcompra, a chance de realmente realizá-la cai drasticamente.\nÉ por isso que os modelos de assinatura e tarifa fixa reinam: você só precisa tomar a decisão uma única vez.\nPara as microtransações menores, isso vale até do ponto de vista econômico. Usando como base um salário de US$ 20 por hora, pensar por dois segundos se algo “vale 21 satoshis” já te custou mais de 1 centavo de dólar, ou seja, mais do que o valor da própria microtransação.\nÉ inviável — psicologicamente e economicamente. Isso, em resumo, é o problema do MTX.\nO Paradoxo do DRM Mas esse não é o único problema que afeta a monetização de conteúdo digital. Como já mencionado, existe também o paradoxo do DRM.\nDRM, ou \u0026ldquo;gestão de direitos digitais\u0026rdquo;, é um esforço inútil para impedir que a informação seja copiada. Deveria ser óbvio que informação não copiável é um contrassenso — mas, em plena era de NFTs e outras bobagens, é melhor deixar isso claro:\nVocê não pode criar informação que não possa ser copiada. Ponto. Como disse Bruce Schneier: “Tentar tornar arquivos digitais não copiáveis é como tentar fazer com que a água não seja molhada.” Por sua própria natureza, se uma informação pode ser lida, ela também pode ser copiada — com fidelidade perfeita.Mas esse não é o único problema que afeta a monetização de conteúdo digital. Como já mencionado, existe também o paradoxo do DRM.\nDRM, ou \u0026ldquo;gestão de direitos digitais\u0026rdquo;, é um esforço inútil para impedir que a informação seja copiada. Deveria ser óbvio que informação não copiável é um contrassenso — mas, em plena era de NFTs e outras bobagens, é melhor deixar isso claro:\nVocê não pode criar informação que não possa ser copiada. Ponto. Como disse Bruce Schneier: “Tentar tornar arquivos digitais não copiáveis é como tentar fazer com que a água não seja molhada.” Por sua própria natureza, se uma informação pode ser lida, ela também pode ser copiada — com fidelidade perfeita. Nenhuma manobra técnica ou restrição artificial muda esse fato.\nÉ por isso que filmes, músicas e outros conteúdos digitais sempre acabam disponíveis de graça por aí. É muito fácil para alguém com acesso a esse conteúdo fazer uma cópia — a custo quase zero — e disponibilizá-lo para outras pessoas.\nLogo, com tempo e popularidade suficientes, todo filme, toda música, todo documento acabará acessível ao público gratuitamente. A natureza da informação não permite outro resultado.\nPor isso se diz: “A informação quer ser livre.” Nenhuma manobra técnica ou restrição artificial muda esse fato.\nÉ por isso que filmes, músicas e outros conteúdos digitais sempre acabam disponíveis de graça por aí. É muito fácil para alguém com acesso a esse conteúdo fazer uma cópia — a custo quase zero — e disponibilizá-lo para outras pessoas.\nLogo, com tempo e popularidade suficientes, todo filme, toda música, todo documento acabará acessível ao público gratuitamente. A natureza da informação não permite outro resultado.\nPor isso se diz: “A informação quer ser livre.” Mas o paradoxo do DRM vai além — e é até engraçado. Embora tentar criar informação incopiável já seja, por si só, uma contradição, não é disso que se trata o verdadeiro paradoxo do DRM. Ele é ainda mais irônico — e, de novo, mais psicológico do que técnico:\nConteúdo só continua preso atrás de paywall se for ruim. Se for bom, alguém vai libertá-lo. Todo mundo sabe disso.\nSe um artigo realmente vale a pena, alguém que tem acesso vai tirar print e postar nas redes sociais. Se o filme é bom, ele vai aparecer em sites que têm barcos piratas no logotipo. Se a música vale a audição, ela vai parar em sites de streaming gratuitos.\nSó os artigos ruins, os filmes obscuros e as músicas que doem nos ouvidos continuam presos atrás de um paywall.\nDaí o paradoxo: se o conteúdo é bom, será libertado. Se continua trancado, é porque provavelmente não presta. MTX é um problema mais grave do que o DRM Pessoalmente, acho que o problema do MTX é bem mais sério do que o paradoxo do DRM. A solução tradicional para o MTX é o modelo de assinatura — tipo Netflix, Spotify, Amazon e por aí vai.\nO paradoxo do DRM ainda existe, mas deixa de ser um problema quando o acesso \u0026ldquo;legítimo\u0026rdquo; à informação é conveniente o suficiente.\nO custo de oportunidade de baixar, guardar, manter e organizar sua coleção privada de músicas é alto demais para a maioria das pessoas. A solução mais prática é simplesmente pagar a assinatura do Spotify.\nDito isso, já começamos a ver os problemas embutidos no próprio modelo de assinaturas.\nE o quadrinho a seguir ilustra isso muito bem…\nTirinha feita por /u/Hoppy_Doodle A proliferação de plataformas de streaming te obriga a assinar Netflix, Amazon Prime, Hulu, Disney Plus, YouTube Premium — e por aí vai. E isso é só para vídeo sob demanda. O mesmo zoológico de assinaturas existe para música, livros, jogos, newsletters, posts de blog, etc.\nEntão, qual é a solução?\nAceite a Natureza da Informação A solução começa pela aceitação. Vender conteúdo digital da forma tradicional, baseada em transações pontuais, não funciona — ou pelo menos não funciona muito bem. Uma transação envolvendo uma fotografia digital de uma maçã é muito diferente de uma envolvendo uma maçã física.\nGeorge Bernard Shaw disse isso da melhor forma: “Se você tem uma maçã e eu tenho uma maçã e trocamos essas maçãs, cada um de nós continuará tendo uma maçã. Mas se você tem uma ideia e eu tenho uma ideia e trocamos essas ideias, cada um de nós terá duas ideias.”\nComo a informação digital se comporta como uma ideia, não faz sentido torná-la artificialmente escassa. Isso é verdade não só filosoficamente, mas também tecnicamente. Computadores são máquinas de copiar. Sempre foram, sempre serão. A única forma de mover informação de uma máquina para outra é copiando-a. Isso por si só já deixa clara a futilidade de tratar informação como objetos físicos.\nQuando se trata de monetizar informação na web aberta, precisamos alinhar nossa forma de pensar com a natureza da informação. Como vimos, informação é não escassa, facilmente copiada, facilmente modificada e quer ser livre.\nAcredito que o modelo certo de monetização precisa respeitar esses valores e ter propriedades semelhantes. Ele precisa ser aberto, transparente, extensível e, por último — mas não menos importante — completamente voluntário.\nEsse modelo tem um nome: valor por valor.\nRevitalizando o Artista de Rua A ideia é simples, mas soa radical: você oferece seu conteúdo gratuitamente, para todos, sem restrições de acesso. Se as pessoas gostarem, se elas perceberem valor no que você oferece, você facilita para que elas devolvam valor.\nPode parecer absurdo nos dias de hoje, mas esse modelo funciona há milhares de anos. É o modelo dos artistas de rua, o modelo dos músicos de calçada, o modelo da doação voluntária. No ciberespaço, porém, não enfrentamos as limitações físicas do artista de rua tradicional. Conteúdo digital escala de maneiras que performances no mundo físico jamais conseguirão.\nO modelo valor-por-valor inverte o modelo tradicional de pagamento. Tradicionalmente, o pagamento precede o desfrute. Na abordagem valor-por-valor, o pagamento segue o desfrute — de forma voluntária.\nVocê é livre para ouvir o músico de rua e seguir seu caminho, mas — e isso a plateia intui naturalmente — se quiser que a música continue, deve jogar algumas moedas no chapéu.\nUma coisa linda desse modelo é que ele realinha os incentivos. Você não fica tentando maximizar cliques, tempo de visualização ou qualquer outra métrica infinita. Você vai querer oferecer valor para sua audiência — e só isso. E se sua audiência tiver tirado valor disso, uma porcentagem vai retribuir. Tudo que você precisa fazer é pedir.\nUma Alternativa Valiosa Estamos apenas no começo dessa mudança monumental. Minha esperança é que o modelo valor-por-valor continue a emergir como uma alternativa viável — uma alternativa à publicidade, censura, banimento e desmonetização.\nO modelo valor-por-valor remove o “eles” da equação. Eles filtram, censuram, desmonetizam, banem. Nem importa quem são esses “eles”. Se um “eles” existir, ele vai encontrar um jeito de estragar tudo.\nValor-por-valor elimina o “eles” e coloca você no comando. Você é o governante no reino do um, único responsável pelos seus pensamentos e sua fala. Se quisermos liberdade (e salvação) no ciberespaço, precisamos colocar o indivíduo no controle novamente. Como sempre, liberdade e independência exigem responsabilidade.\nNo melhor dos mundos, os criadores são incentivados a fazer apenas uma coisa: criar. Atendendo só a si mesmos e àqueles interessados em suas criações. Sem intermediários. Direto, pessoa a pessoa, valor por valor.\nO Que Está Por Vir É verdade que, hoje, não é tão simples hospedar sua própria infraestrutura. É intimidante rodar seu próprio nó para receber pagamentos de forma autosoberana. Mas, além de ficar mais fácil, isso será cada vez mais necessário.\nAlém de facilitar tudo, precisamos estar atentos ao problema do MTX descrito acima. Cada passo que reduzir o custo mental das transações no ecossistema valor-por-valor é um passo na direção certa.\nA capacidade de valor do Podcasting 2.0 é um desses passos. Ela permite e automatiza pagamentos por minuto, sem nenhuma interação extra do usuário. Uma vez configurado, sua carteira fará os pagamentos automaticamente.\nAcredito que futuras versões dessa ideia poderão ser integradas a todos os tipos de mídia, seja áudio, vídeo, imagens, texto e por aí vai. Acredito que estamos perto da versão protocolar do Patreon: todos os benefícios de zerar os custos mentais de transação, sem o atrito e a censura inerentes a uma solução baseada em plataforma.\nSe isso virá na forma de pagamentos recorrentes BOLT12 ou algo totalmente diferente ainda é cedo para dizer. Tenho confiança, no entanto, de que vai chegar — e a seu tempo.\nConclusão Não só nosso dinheiro fiduciário está quebrado, como também o modelo de monetização da internet está falho. As plataformas baseadas em publicidade dos dias de hoje otimizam o engajamento por meio da divisão e polarização, usando padrões obscuros e vício planejado.\nNão será fácil escapar dos ciclos compulsivos que foram armados para nós, mas graças à pilha tecnológica autosoberana que está surgindo, existe uma alternativa viável: o modelo valor-por-valor.\nO modelo de monetização do “artista de rua” funcionou por muitos séculos no passado, e graças ao Bitcoin e à Lightning Network, estou confiante de que funcionará por muitos séculos no futuro. Estamos quase lá. Só precisamos descobrir como posicionar o chapéu corretamente no chão e quais são os melhores lugares da cidade para se apresentar, por assim dizer.\nValor-por-valor elimina completamente o paradoxo do DRM e — com o nível certo de automação e configurações sensatas — também resolverá o problema do MTX.\nSe acertarmos isso, poderemos nos libertar do ambiente evolutivo de sobrevivência do mais rico das plataformas, permitindo que entremos no reino quase imortal dos protocolos.\nHá muito a explorar, muitas ferramentas a construir e muitas noções preconcebidas a serem quebradas. Uma mudança sísmica está acontecendo bem diante dos nossos olhos, e estou ansioso para surfar essas ondas com todos vocês. Avante!\n","permalink":"https://blog.batcode.io/posts/liberdade-valor/","summary":"\u003cp\u003eBaseado no artigo original The Freedom of Value de Gigi, esta tradução e adaptação seguem os termos disponibilizados em dergigi.com/translations, sob a licença \u003ca href=\"https://creativecommons.org/licenses/by-sa/4.0/\"\u003eCreative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eCom a palavra, o autor:\u003c/p\u003e\n\u003cp\u003eA internet tem um problema. Poucas pessoas sabem que esse problema existe, mas, veja bem, essa é a natureza dos problemas sérios e não óbvios: eles permanecem invisíveis — até que deixam de ser.\nO problema da internet é que a informação quer ser livre. E, se algo quer ser livre no sentido de liberdade, com tempo suficiente, também acabará sendo livre no sentido de \u0026ldquo;gratuito\u0026rdquo;.\u003c/p\u003e","title":"A Liberdade do Valor: Como o Valor-por-Valor pode corrigir a forma como monetizamos a informação."},{"content":"O Kafka, fundamentalmente, opera com um modelo de publicação/assinatura (PubSub) e transmite mensagens como sequências de bytes, mantendo-se agnóstico quanto ao conteúdo trafegado. Esta característica é crucial para sua notável performance. Contudo, durante a serialização, o Kafka converte as informações em bytes para transmissão, exigindo que o consumidor realize a desserialização desses bytes para um formato legível.\nEsta arquitetura desacoplada de produtores e consumidores, embora poderosa, apresenta desafios significativos. O mais crítico deles é a alteração ou remoção de campos nos dados transmitidos. Tais mudanças, frequentemente resultantes de comunicação inadequada ou documentação insuficiente, podem comprometer seriamente a integridade de qualquer arquitetura de software.\nO Kafka trabalha com os conceitos de PubSub e ao transmitir as mensagens como bytes, ele não tem visão do conteúdo que está sendo trafegado. Para abordar esses desafios e garantir uma integração robusta entre Kafka e Avro Schema, exploraremos estratégias que não apenas melhoram a eficiência do processamento de dados, mas também fortalecem a resiliência do sistema contra mudanças estruturais imprevistas.\nProblemas com a comunicação entre sistemas podem ser frustrantes e difíceis de resolver. Duas abordagens comuns, mas ineficientes, são:\nCapturar exceções dos erros: Isso pode tornar o código difícil de manter e repleto de métodos desnecessários. Decorar ou documentar no código os campos obrigatórios: Além de ser propenso a erros, é fácil esquecer de atualizar a documentação e lembrar quais campos enviar após um longo período. quem nunca se viu nessa situação? Uma solução eficaz é adotar um contrato de dados, e é aí que o Apache Avro entra em cena. O Avro é um sistema de serialização de dados que permite definir esquemas para os dados trocados entre sistemas.\nPara melhorar ainda mais o processo, o Schema Registry da Confluent pode ser utilizado para versionar os esquemas e garantir a compatibilidade entre produtores (publishers) e consumidores (subscribers) de dados no Apache Kafka.\nO Schema Registry é uma ferramenta que oferece a capacidade de armazenar metadados e versioná-los, de forma semelhante a um sistema de controle de versão como o Git. Por meio de APIs REST, é possível armazenar e recuperar esses metadados, que atualmente suportam os formatos Avro, JSON Schema e Protobuf.\nAlém dessas funcionalidades, o Schema Registry fornece classes de serialização e desserialização que se integram com os clientes do Apache Kafka. Essas classes auxiliam na recuperação e no tratamento das mensagens armazenadas no Kafka, garantindo que os dados estejam em conformidade com os esquemas definidos.\nAo utilizar o Apache Avro e o Schema Registry em conjunto com o Apache Kafka, é possível estabelecer um contrato de dados claro e versionar os esquemas, evitando problemas de compatibilidade e facilitando a manutenção e evolução dos sistemas envolvidos na comunicação.\nConfluent Schema Registry — fonte: https://docs.confluent.io/platform/current/schema-registry/index.html JSON — para todos os lados JSON (JavaScript Object Notation) é, sem dúvidas, o formato mais conhecido, fácil de usar e onipresente em todas as aplicações modernas escritas atualmente. Acaba sendo uma escolha muito comum para transmitir mensagens, porém, temos uma faca de dois gumes aqui: alta flexibilidade e zero restrição, o que pode levar a problemas de alterações desavisadas. Prós:\nPodemos criar estruturas complexas (matrizes ou elementos aninhados); É o formato mais aceito na Internet atualmente; Interoperabilidade com quase todas as linguagens (até Cobol); Legível por humanos; Contras:\nNão tem suporte nativo a schemas; Pode se tornar enorme devido à repetição de chaves ao criar objetos complexos; Falta de suporte à documentação e metadados; { \u0026#34;nome\u0026#34;: \u0026#34;João\u0026#34;, \u0026#34;idade\u0026#34;: 30, \u0026#34;endereco\u0026#34;: { \u0026#34;rua\u0026#34;: \u0026#34;Rua A\u0026#34;, \u0026#34;numero\u0026#34;: 123 } } Exemplo utilizando JSON Protobuf — tá na boca do povo no últimos tempos Criado pela Google, este protocolo de comunicação é utilizado na criação de serviços sob gRPC que roda nativamente sobre HTTP/2. Trabalhar com Protobuf é bem simples: primeiramente, é definido o contrato (formato .proto), que é copiado para todos os projetos que se comunicarão entre si. No Java, existem plugins do Maven/Gradle que geram as classes em tempo de compilação, facilitando o processo. Prós:\nRápido devido ao trabalho com binários; Interoperabilidade com quase todas as linguagens; Suporte para streaming (tanto parâmetro de método quanto como resposta); Popularmente utilizado para integração sistêmica; Possui suporte à geração de classes a partir de um \u0026ldquo;contrato\u0026rdquo; (arquivo .proto); Facilita a evolução dos contratos; Contras:\nCurva de aprendizado; Não legível por humanos (ferramentas auxiliares ajudam no consumo de APIs/gRPC, por exemplo); syntax = \u0026#34;proto3\u0026#34;; message Person { string name = 1; int32 age = 2; Address address = 3; } message Address { string street = 1; int32 number = 2; } *Exemplo utilizando Protobuf* Apache Avro — confia! O Apache Avro é um componente de (des)serialização de dados desenvolvido pelo time do Apache Hadoop. Além da comunidade de Big Data, tem forte apoio da Confluent para uso em conjunto com o Schema Registry. Ele utiliza a estrutura JSON para definir os tipos de dados, permite a criação de objetos complexos, multi-schema e documentação embarcada. O transporte da mensagem ocorre de forma binária após o produtor realizar a serialização.\nSemelhante a um banco de dados SQL, você deverá criar primeiramente o esqueleto, ou seja, precisa definir toda a estrutura que um objeto Avro precisa para ser criado e receber dados.\n{ \u0026#34;type\u0026#34;: \u0026#34;record\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Person\u0026#34;, \u0026#34;fields\u0026#34;: [ {\u0026#34;name\u0026#34;: \u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, {\u0026#34;name\u0026#34;: \u0026#34;age\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;int\u0026#34;}, {\u0026#34;name\u0026#34;: \u0026#34;address\u0026#34;, \u0026#34;type\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;record\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Address\u0026#34;, \u0026#34;fields\u0026#34;: [ {\u0026#34;name\u0026#34;: \u0026#34;street\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, {\u0026#34;name\u0026#34;: \u0026#34;number\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;int\u0026#34;} ] }} ] } *Exemplo utilizando Avro Schema* Isso pode ser feito por meio de um arquivo de esquema JSON, que define os campos, tipos de dados e a estrutura do objeto Avro. Uma vez definido o esquema, você pode usá-lo para serializar e desserializar dados de forma eficiente e compatível entre diferentes sistemas.\nO Avro se destaca por sua capacidade de lidar com a evolução dos esquemas ao longo do tempo, permitindo que os produtores e consumidores trabalhem com versões diferentes dos dados sem perder a compatibilidade. Isso é especialmente útil em ambientes distribuídos, como no Apache Kafka, onde múltiplos sistemas precisam se comunicar de forma confiável e escalável.\nO Avro Schemas oferece suporte a tipos primitivos (int, string, boolean, long, double e etc), tipos lógicos (date, timestamp-millis, decimal e etc) e records (que são os \u0026ldquo;objetos\u0026rdquo;). Para entender e consultar todos os tipos aceitos pelo Avro, sugiro que leia a documentação oficial.\nO que torna o Avro Schemas tão confiável é que ele não permite que dados sem schema sejam considerados objetos válidos, diferente do JSON. Além disso, ao utilizar o Avro em conjunto com o Schema Registry, é possível evoluir os schemas ao longo do tempo e trabalhar com múltiplas versões entre produtores e consumidores. A curva de aprendizado não é elevada, pois o Avro utiliza uma estrutura semelhante ao JSON.\nAbaixo um trecho de código funcional usando tipos complexos.\n{ \u0026#34;namespace\u0026#34;: \u0026#34;avro.example.entity\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;record\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;UserAvroEntity\u0026#34;, \u0026#34;fields\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;avro.java.string\u0026#34;: \u0026#34;String\u0026#34;, \u0026#34;doc\u0026#34;: \u0026#34;Full name of User\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;age\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;int\u0026#34;, \u0026#34;doc\u0026#34;: \u0026#34;Age at the time of registration\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;birth\u0026#34;, \u0026#34;type\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;int\u0026#34;, \u0026#34;logicalType\u0026#34;: \u0026#34;date\u0026#34; }, \u0026#34;doc\u0026#34;: \u0026#34;User\u0026#39;s birthdate\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;money\u0026#34;, \u0026#34;type\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;bytes\u0026#34;, \u0026#34;logicalType\u0026#34;: \u0026#34;decimal\u0026#34;, \u0026#34;precision\u0026#34;: 8, \u0026#34;scale\u0026#34;: 2 } }, { \u0026#34;name\u0026#34;: \u0026#34;registration_date\u0026#34;, \u0026#34;type\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34;, \u0026#34;logicalType\u0026#34;: \u0026#34;timestamp-millis\u0026#34; } } ] } Ao utilizar o Avro Schema com Java, temos plugins para Maven/Gradle que permitem gerar as classes a partir do arquivo .asvc criado. No entanto, o Avro utiliza algumas classes \u0026ldquo;não amigáveis\u0026rdquo; por padrão. Por exemplo, campos string do Avro Schema são gerados como CharSequence em classes Java, e BigDecimal é tratado como ByteBuffer, perdendo a escala dos campos. Mas há soluções para resolver esses problemas.\nAs diferenças em relação ao Avro anterior são:\nCampos com LogicalType date serão gerados com o tipo LocalDate do Java (ou JodaTime); Campos com type String serão gerados como o tipo String do Java (em vez de CharSequence); Campos com o LogicalType timestamp-millis são gerados como o tipo Instant do Java; Além dessas anotações no arquivo Avro, é necessário configurar alguns parâmetros do plugin responsável por compilar o arquivo .avsc e gerar as classes.\nExemplo de configuração do plugin no Maven:\n\u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.apache.avro\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;avro-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.10.2\u0026lt;/version\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;phase\u0026gt;generate-sources\u0026lt;/phase\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;schema\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;sourceDirectory\u0026gt;${project.basedir}/src/main/avro/\u0026lt;/sourceDirectory\u0026gt; \u0026lt;outputDirectory\u0026gt;${project.basedir}/src/main/java/\u0026lt;/outputDirectory\u0026gt; \u0026lt;stringType\u0026gt;String\u0026lt;/stringType\u0026gt; \u0026lt;enableDecimalLogicalType\u0026gt;true\u0026lt;/enableDecimalLogicalType\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; Vou ser bonzinho e deixar um exemplo funcional para usar no Gradle.\nplugins { id(\u0026#34;java\u0026#34;) id(\u0026#34;com.github.davidmc24.gradle.plugin.avro\u0026#34;) version \u0026#34;1.2.0\u0026#34; } group = \u0026#34;com.example\u0026#34; version = \u0026#34;1.0-SNAPSHOT\u0026#34; repositories { mavenCentral() } dependencies { implementation(\u0026#34;org.apache.avro:avro:1.10.2\u0026#34;) } avro { setStringType(\u0026#34;String\u0026#34;) setFieldVisibility(\u0026#34;private\u0026#34;) setCreateOptionalGetters(true) setGettersReturnOptional(true) setOptionalGettersForNullableFieldsOnly(true) setCreateSetters(true) setEnableDecimalLogicalType(true) } tasks.generateAvroJava { source(\u0026#34;src/main/avro\u0026#34;) setOutputDir(file(\u0026#34;src/main/java\u0026#34;)) } tasks.compileJava { source(tasks.generateAvroJava) } A última recomendação é definir a propriedade spring.kafka.properties.specific.avro.reader=true no arquivo de properties do projeto. Isso fará com que a desserialização do Avro seja \u0026ldquo;forçada\u0026rdquo; para o nome Avro específico, garantindo a correta interpretação dos dados.\nEstou disponibilizando um exemplo prático no Github, onde você pode encontrar um projeto simples demonstrando o uso do Avro com Kafka. Para realizar os testes, basta compilar o projeto e verificar a classe UserAvroEntity. Também é possível subir o ambiente com o docker-compose e acessar http://localhost:9091 para criar um novo tópico e registrar o schema Avro contido no projeto.\nConclusão Neste artigo, exploramos a integração do Apache Kafka, Schema Registry e Apache Avro para garantir uma comunicação eficiente e confiável entre sistemas. O Kafka se destaca como uma plataforma de streaming de dados altamente escalável e performática, enquanto o Schema Registry da Confluent oferece uma solução robusta para gerenciar e versionar os schemas, assegurando a compatibilidade e evolução dos dados.\nO Apache Avro, com seu formato de serialização flexível e suporte a tipos primitivos, lógicos e records, permite a criação de schemas ricos e expressivos. Através de exemplos práticos, demonstramos como definir schemas Avro, utilizar tipos lógicos e gerar classes Java a partir dos schemas usando plugins do Maven e Gradle.\nA adoção conjunta do Kafka, Schema Registry e Avro possibilita a construção de pipelines de dados escaláveis e confiáveis, permitindo a evolução dos schemas ao longo do tempo e mantendo a compatibilidade entre produtores e consumidores. Embora haja uma curva de aprendizado inicial, os benefícios a longo prazo compensam o investimento.\nEm resumo, a combinação do Apache Kafka, Schema Registry e Apache Avro forma uma base sólida para o desenvolvimento de sistemas de streaming de dados robustos e flexíveis. Ao aproveitar essas tecnologias, as organizações podem lidar com a crescente complexidade e volume de dados, garantindo a integridade e compatibilidade dos mesmos.\nEspero que este artigo tenha fornecido insights valiosos sobre o uso do Kafka, Schema Registry e Avro. Lembre-se de que a jornada de aprendizado é contínua, e sempre há mais para explorar e aprimorar. Fique atento às atualizações e às melhores práticas recomendadas pela comunidade, e também pela própria Confluent e continue aprimorando suas habilidades nessas tecnologias poderosas.\nSe você tiver alguma dúvida, sugestão ou feedback, não hesite em entrar em contato. Estou sempre disponível para ajudar e trocar ideias. Agradeço por acompanhar este artigo até o fim e espero que você tenha encontrado valor nele.\nAté a próxima!\n","permalink":"https://blog.batcode.io/posts/apache-kafka/","summary":"\u003cp\u003eO Kafka, fundamentalmente, opera com um modelo de publicação/assinatura (PubSub) e transmite mensagens como sequências de bytes, mantendo-se agnóstico quanto ao conteúdo trafegado. Esta característica é crucial para sua notável performance. Contudo, durante a serialização, o Kafka converte as informações em bytes para transmissão, exigindo que o consumidor realize a desserialização desses bytes para um formato legível.\u003c/p\u003e\n\u003cp\u003eEsta arquitetura desacoplada de produtores e consumidores, embora poderosa, apresenta desafios significativos. O mais crítico deles é a alteração ou remoção de campos nos dados transmitidos. Tais mudanças, frequentemente resultantes de comunicação inadequada ou documentação insuficiente, podem comprometer seriamente a integridade de qualquer arquitetura de software.\u003c/p\u003e","title":"Apache Kafka com Avro Schema: (des)serialização eficiente de dados complexos e evolução de schemas em sistemas distribuídos."},{"content":"Douglas Santos, também conhecido como Batman. Engenheiro de software, gamer e aspirante a criptógrafo.\nEscrevo aqui sobre sistemas distribuídos, Linux e as coisas que quebram no caminho — em português, e às vezes também em inglês.\nGitHub: @odouglsantos LinkedIn: odouglsantos E-mail: douglas@batcode.io ","permalink":"https://blog.batcode.io/about/","summary":"\u003cp\u003eDouglas Santos, também conhecido como Batman. Engenheiro de software, gamer e\naspirante a criptógrafo.\u003c/p\u003e\n\u003cp\u003eEscrevo aqui sobre sistemas distribuídos, Linux e as coisas que quebram no\ncaminho — em português, e às vezes também em inglês.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGitHub: \u003ca href=\"https://github.com/odouglsantos\"\u003e@odouglsantos\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eLinkedIn: \u003ca href=\"http://www.linkedin.com/in/odouglsantos/\"\u003eodouglsantos\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eE-mail: \u003ca href=\"mailto:douglas@batcode.io\"\u003edouglas@batcode.io\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"Sobre"}]