Software local-first: ter meus dados mesmo na era da nuvem (2019)
(inkandswitch.com)- Os apps em nuvem melhoraram muito a colaboração e o acesso em vários dispositivos, mas, como a cópia autorizada dos dados fica no servidor, a propriedade e o controle do usuário enfraquecem
- O software local-first mantém o armazenamento local de notebooks, tablets e celulares como cópia principal dos dados, limitando o servidor a um papel auxiliar de sincronização e backup
- Essa abordagem busca ao mesmo tempo resposta rápida, trabalho offline, sincronização entre vários dispositivos, colaboração em tempo real, preservação de longo prazo e segurança e privacidade por padrão
- Arquivos, email, apps web, sincronização ao estilo Dropbox, Git, Firebase, CloudKit, Realm e CouchDB têm algumas vantagens, mas não satisfazem ao mesmo tempo colaboração e propriedade dos dados
- Protótipos baseados em CRDT e Automerge mostraram potencial, mas ainda restam desafios como desempenho, comunicação em rede, estabilidade de P2P e UI de documentos distribuídos
O conflito entre colaboração em nuvem e propriedade dos dados
- Apps em nuvem como Google Docs, Figma, Slack e Trello são acessados pelo navegador ou por apps móveis e armazenam os dados no servidor
- Esse modelo oferece as vantagens da colaboração em tempo real e do acesso de qualquer lugar, mas todo acesso aos dados precisa passar pelo servidor
- Só é possível fazer o que o servidor permite
- Se o serviço sair do ar, o acesso não apenas ao software, mas também aos dados criados com ele, pode ser bloqueado
- Mesmo que seja possível exportar os dados, é difícil continuar executando o mesmo software sem o servidor
- Em contrapartida, apps locais mais antigos leem e gravam arquivos no disco local, então o usuário pode controlar diretamente backup, retenção de longo prazo, manipulação por outros programas e exclusão
- A tensão central é que a nuvem oferece colaboração, enquanto os apps locais oferecem propriedade; o local-first é uma direção de design que tenta obter os dois ao mesmo tempo
O modelo básico do software local-first
- O software local-first prioriza o armazenamento local e a rede local em vez de servidores em datacenters remotos
- Em apps em nuvem, os dados no servidor são a fonte autorizada, e os dados no cliente são mais próximos de um cache subordinado ao servidor
- Em apps local-first, os dados locais de cada dispositivo são a cópia principal, enquanto o servidor mantém cópias auxiliares para ajudar no acesso por vários dispositivos e no backup
- Essa mudança de perspectiva afeta diretamente desempenho, uso offline, preservação de longo prazo, privacidade e controle do usuário
Os 7 ideais do local-first
-
1. Operações imediatas, sem spinner
- Apps em nuvem exigem ida e volta ao servidor para modificar dados e para muitas consultas, então há latência
- A Optimistic UI esconde a latência ao fazer parecer que a solicitação já terminou, mas, se houver erro de rede, a demora volta a aparecer
- Em apps local-first, como os dados principais estão no dispositivo local, a entrada do usuário precisa esperar menos pela resposta do servidor
- A sincronização ocorre em segundo plano, e o app pode reagir à entrada quase de forma imediata
-
2. Trabalho que não fica preso a um único dispositivo
- Os usuários alternam entre vários dispositivos, como capturar ideias no smartphone, organizá-las no tablet e documentá-las no notebook
- Apps local-first também precisam de sincronização entre todos os dispositivos de trabalho, mesmo mantendo os dados em cada dispositivo
- A maioria dos serviços de sincronização entre dispositivos também salva uma cópia no servidor, funcionando como backup off-site
- Quando várias pessoas editam o mesmo arquivo ao mesmo tempo, podem surgir conflitos, então o design da colaboração se torna importante
-
3. Rede como opção
- Aviões, túneis, elevadores, estacionamentos, Wi‑Fi instável, custos de roaming e ambientes de internet incompleta em países em desenvolvimento e áreas rurais criam a necessidade de trabalho offline
- Apps em nuvem em geral são fracos offline, e também é difícil adicionar suporte offline tardiamente a um modelo centrado no servidor
- Apps local-first armazenam os dados principais no sistema de arquivos local de cada dispositivo, então é possível ler e gravar mesmo offline
- Depois, quando a rede estiver disponível, eles sincronizam com outros dispositivos, e a sincronização pode acontecer não só pela internet, mas também por Bluetooth ou Wi‑Fi local
- Para uma boa experiência offline, um executável instalado localmente é mais adequado do que uma aba do navegador
-
4. Colaboração fluida com colegas
- Softwares antigos baseados em arquivos locais tendem a gerar conflitos quando várias pessoas editam o mesmo arquivo ao mesmo tempo
- Apps em nuvem como Google Docs popularizaram a experiência em que vários usuários editam um documento ao mesmo tempo sem se preocupar com conflitos
- O ideal do local-first é oferecer colaboração em tempo real igual ou melhor que a dos melhores apps em nuvem de hoje
- Também é importante um fluxo em que um usuário propõe mudanças e outro as revisa para aplicá-las seletivamente
- suggesting mode do Google Docs
- pull request do GitHub
-
5. Long Now: acessibilidade de longo prazo
- Um aspecto importante da propriedade dos dados é poder acessá-los por muito tempo no futuro
- Apps locais antigos podem continuar sendo usados se houver uma cópia dos dados e do software executável, e até sistemas operacionais ou computadores antigos podem ser executados em máquinas virtuais ou emuladores
- Mesmo que a mídia de armazenamento mude, os arquivos podem ser copiados para a nova mídia
- Apps em nuvem dependem da premissa de que o serviço continuará sendo oferecido e são vulneráveis a encerramento do serviço, perda de dados, mudanças de preço ou funcionalidade e upgrades forçados indesejados
- O software local-first aumenta a chance de preservação de longo prazo porque os dados e o software que lê e modifica esses dados ficam armazenados localmente
- plain text, JPEG e PDF têm alta chance de continuar legíveis por muito tempo, e a Biblioteca do Congresso dos EUA recomenda XML, JSON e SQLite como formatos de preservação para datasets
-
6. Segurança e privacidade como padrão
- Apps em nuvem reúnem os dados de todos os usuários em um banco de dados central, tornando-se um alvo atraente para atacantes
- Funcionários internos ou hackers com acesso ao servidor podem ler ou manipular os dados, e vazamentos de dados continuam sendo um risco frequente
- Os termos do Google Drive afirmam que sistemas automatizados analisam o conteúdo do usuário para oferecer resultados de busca personalizados e detectar spam e malware
- Para usuários que lidam com dados sensíveis, como profissionais de saúde, jornalistas investigativos e pessoas ligadas ao governo e à diplomacia, usar apps em nuvem pode entrar em conflito com obrigações regulatórias e de confidencialidade
- Apps local-first podem armazenar em cada dispositivo local apenas os dados do próprio usuário, mantendo no servidor apenas cópias criptografadas de ponta a ponta
- iMessage, WhatsApp, Signal, Keybase e Tarsnap são apresentados como exemplos de criptografia de ponta a ponta ou de compartilhamento e backup de arquivos criptografados
-
7. Propriedade e controle finais
- Em apps em nuvem, o provedor do serviço pode restringir o acesso do usuário
- Em outubro de 2017, alguns usuários do Google Docs tiveram o acesso a documentos bloqueado porque sistemas automáticos marcaram os documentos incorretamente como maliciosos
- Aqui, propriedade não significa direito de propriedade intelectual, mas agência do usuário, autonomia e controle sobre os dados
- No software local-first, como os bytes que compõem os dados estão no dispositivo do usuário, há liberdade para processá-los da forma desejada
- A propriedade dos dados também traz a responsabilidade de manter backups, evitar perda de dados, responder a ransomware e gerenciar arquivos de arquivo morto
- O local-first não precisa necessariamente ser open source; software comercial e fechado também pode se aproximar desse ideal se não limitar artificialmente o uso dos arquivos
- Como exemplos de restrições artificiais, são citados PDF que impede impressão, leitores de eBook que atrapalham copiar e colar e DRM em arquivos de mídia
Limitações dos modelos existentes de armazenamento e compartilhamento
-
Arquivos e anexos de e-mail
- Arquivos tradicionais são fortes em visualização e edição offline, controle do usuário, backup, preservação de longo prazo e acesso rápido
- Para acesso em vários dispositivos, são necessários métodos como e-mail, USB, NAS/NFS/FTP/rsync, sincronização de arquivos no estilo Dropbox e Git
- Anexos de e-mail são fáceis de entender e confiáveis, e mesmo depois de 6 meses o arquivo anexado continua na forma original
- O ponto fraco é a colaboração
- Em geral, apenas uma pessoa pode modificar o arquivo por vez
- Quando várias pessoas editam, é necessário fazer merge manual
- Surge a confusão de nomes de arquivo como
Budget draft 2 (Jane's version) final final 3.xls
- Apps que tentam aplicar a ideia local-first podem começar oferecendo exportação para formatos amplamente suportados, como plain text, PDF, PNG e JPEG
-
Apps web
- Apps web como Google Docs, Trello, Figma e Pinterest têm navegador ou app mobile como cliente leve, enquanto o armazenamento de dados fica no servidor
- Os apps web estabeleceram o padrão de colaboração em tempo real e têm a grande vantagem, no trabalho em equipe, de permitir ver a versão mais recente de qualquer lugar
- Em contrapartida, a propriedade e o controle diminuem bastante
- Os dados do servidor são a referência, e os dados do cliente ficam mais próximos de um cache
- Mesmo uma breve interrupção de rede pode bloquear o acesso no meio do trabalho
- Suporte offline limitado, como o offline plugin do Google Docs, está mais para algo acrescentado depois a uma arquitetura centrada no servidor
- Mesmo clientes desktop instaláveis, como Milanote e Figma, são essencialmente navegadores reempacotados, então suas limitações aparecem em situações de falha de rede, indisponibilidade do servidor ou encerramento do serviço
-
Dropbox, Google Drive, Box, OneDrive
- Dropbox, Google Drive, Box e OneDrive monitoram uma pasta designada no desktop e copiam os arquivos alterados para outros computadores
- Como usam o sistema de arquivos local, são rápidos e permitem trabalho offline; mesmo que o serviço de sincronização seja encerrado, os arquivos no disco local permanecem
- Se ocorrer uma falha no disco rígido, é possível restaurar instalando o app e aguardando a sincronização, o que traz vantagens em termos de longevidade e controle
- No iOS e no Android móveis, eles ficam mais próximos de um modelo de cliente leve, no qual não sincronizam a pasta inteira e buscam os arquivos um a um no servidor
- A opção “Make available offline” precisa ser definida antecipadamente, é incômoda e só funciona enquanto o app está aberto
- O ponto mais fraco é a colaboração em tempo real
- Se o mesmo arquivo for modificado em dois dispositivos, surgem conflitos que exigem merge manual
- O fato de poder sincronizar formatos de arquivo arbitrários é uma vantagem de compatibilidade, mas também é uma fraqueza, porque não permite merge por formato
-
Git e GitHub
- Git e GitHub são usados principalmente para colaboração em código-fonte e são avaliados atualmente como o pacote de software mais próximo do local-first
- O repositório Git é a cópia principal dos dados no sistema de arquivos local e não depende do servidor
- Ele oferece trabalho totalmente offline, operação rápida, controle do usuário e adequação para preservação de longo prazo
- O GitHub oferece colaboração, acesso por vários dispositivos, backup e local de arquivamento, mas não criptografa o repositório
- O Git tem duas grandes fraquezas
- Não há colaboração com merge automático fino e em tempo real como no Google Docs, Trello ou Figma
- Ele é otimizado para código e texto baseado em linhas, e outros formatos de arquivo são tratados como blobs binários difíceis de editar e mesclar de forma significativa
- O fato de muitos engenheiros de software apontarem “é lento”, “não confio” e “quero manter meu código no sistema local” como motivos para evitar editores e ambientes de execução baseados em nuvem, como Cloud9, Repl.it e Colaboratory, está ligado às motivações do local-first
Opções do ponto de vista da infraestrutura para desenvolvedores
-
Apps web de cliente leve
- É um modelo em que servidores Rails, Django, PHP ou Node.js armazenam dados em bancos SQL ou NoSQL e entregam páginas web via HTTPS
- Não é necessária instalação, o usuário só precisa visitar uma URL, e a responsabilidade pela gestão dos dados fica com a equipe de engenharia e DevOps que fez o deploy
- Meteor, ShareDB, Pusher, Ably e WebSocket facilitam adicionar recursos de colaboração em tempo real a apps web
- Se cada ação do usuário exigir uma requisição ao servidor, tudo fica lento, e mesmo que o JavaScript no cliente esconda o tempo de ida e volta, isso quebra facilmente em uma internet instável
- Apesar de esforços como manifest, localStorage, service worker e Progressive Web Apps, a arquitetura de apps web continua fundamentalmente centrada no servidor
- Ao apagar os cookies no navegador, muitas vezes os dados do armazenamento local também são apagados junto, então isso não é adequado para armazenar dados importantes no longo prazo
- Se o usuário hospedar diretamente um app web open source, algumas características podem melhorar, mas como a maioria das pessoas não quer virar administradora de sistemas, self-hosting não é uma opção realista para a maioria
-
Apps mobile que usam armazenamento local
- Apps de iOS e Android baixam um binário e o instalam localmente, mas muitos apps, como Twitter, Yelp e Facebook, são clientes leves que só funcionam com servidor
- Apps que primeiro armazenam dados no dispositivo local com uma camada de persistência como SQLite, Core Data ou arquivos comuns estão mais próximos do ideal local-first
- Clue e Things são exemplos que começaram como apps para um único usuário e depois adicionaram um backend em nuvem para sincronização entre dispositivos ou compartilhamento
- Esses apps de cliente mais robusto são rápidos e funcionam offline porque a sincronização com o servidor acontece em segundo plano
- A dificuldade aumenta quando vários dispositivos ou vários usuários colaborativos modificam os dados
- Desenvolvedores de apps mobile geralmente são especialistas em apps para o usuário final, não em sistemas distribuídos
- Algoritmos improvisados de diff, merge e resolução de conflitos costumam ser pouco confiáveis e frágeis
-
Firebase, CloudKit, Realm
- Firebase é um BaaS mobile que combina banco de dados local no dispositivo, serviço de banco de dados em nuvem e sincronização entre os dois lados
- O Firebase oferece suporte a compartilhamento entre vários dispositivos e uso offline, mas, por ser um serviço de hospedagem proprietário, tem pontuação baixa em privacidade e longevidade
- O Parse foi adquirido pelo Facebook e depois encerrado em 2017, o que obrigou apps que dependiam dele a migrar para outros backends
- O console do Firebase oferece uma boa experiência para desenvolvedores visualizarem, modificarem e excluírem dados, mas os usuários não têm meios equivalentes para acessar, manipular e gerenciar seus próprios dados
- O CloudKit da Apple oferece uma experiência parecida com a do Firebase para apps que podem se limitar a iOS e Mac
- Armazenamento de chave-valor e sincronização
- Bons recursos offline
- Por ser integrado à plataforma, reduz o incômodo de criar conta e fazer login
- O Realm ganhou popularidade como biblioteca de persistência local para iOS, e o Realm Object Server pode ser open source e auto-hospedado, reduzindo o risco de dependência do serviço
-
CouchDB
- O CouchDB chama atenção por sua abordagem de replicação multi-master, na qual várias máquinas têm uma cópia completa do banco de dados e cada réplica pode criar alterações de forma independente
- O Cloudant é a versão hospedada, e PouchDB e Hoodie usam o mesmo protocolo de sincronização, mas foram projetados para rodar em dispositivos do usuário final
- Filosoficamente, o CouchDB é próximo dos princípios local-first, mas, quando há dados modificados ao mesmo tempo, o código da aplicação precisa resolver explicitamente os conflitos
- Em apps de colaboração detalhada, como o Google Docs, em que cada tecla digitada pode se tornar uma alteração individual, é difícil escrever código correto de resolução de conflitos
- Entre os motivos apontados para sua adoção limitada estão a escalabilidade de bancos separados por usuário, a necessidade de embutir um cliente JavaScript em apps nativos de iOS e Android, a resolução de conflitos e a estranheza do modelo de consultas MapReduce
CRDT e uma base tecnológica melhor
- As camadas de dados existentes para desenvolvimento de aplicações não atendem a todos os ideais do local-first
- A Ink & Switch pesquisa isso há três anos em busca de uma solução e apresenta os Conflict-free Replicated Data Types, ou CRDT, como uma base promissora
- CRDT é uma estrutura de dados de uso geral que surgiu na pesquisa acadêmica em ciência da computação em 2011
- Assim como estruturas de dados como hash maps e listas armazenam o estado de um documento, mas foram pensados desde o início para ambientes com múltiplos usuários
- Editores de texto, planilhas e apps de gráficos vetoriais mantêm o estado de seus documentos em estruturas de dados, e em apps colaborativos com múltiplos usuários isso pode ser substituído por CRDTs
-
Como funciona a mesclagem em CRDT
- O usuário pode ver e modificar o estado da aplicação no dispositivo local mesmo offline
- O CRDT rastreia as mudanças e sincroniza em segundo plano com outros dispositivos quando a rede está disponível
- Se novos afazeres forem adicionados ao mesmo tempo em dispositivos diferentes, o estado mesclado incluirá todos os itens adicionados em uma ordem consistente
- Alterações simultâneas em objetos diferentes podem ser mescladas com facilidade
- O caso em que a resolução automática é mais difícil é quando vários usuários atualizam ao mesmo tempo a mesma propriedade do mesmo objeto; o CRDT rastreia os valores em conflito e deixa a resolução para o app ou para o usuário
- O CRDT é parecido com o Git, mas funciona com tipos de dados mais ricos do que arquivos de texto
- O canal de sincronização pode ser qualquer um: servidor, conexão P2P, Bluetooth, pen drive etc.
- A unidade de mudança pode ser tão pequena quanto uma única tecla digitada, permitindo colaboração em tempo real no estilo Google Docs, ou pode ser enviada em blocos maiores, como um pull request do Git
-
Automerge e Hypermerge
- A Ink & Switch desenvolveu a implementação open source de CRDT em JavaScript Automerge
- O Automerge se baseia em pesquisas sobre JSON CRDT
- Ao combinar o Automerge com a stack de rede Dat, eles criaram o Hypermerge
- É difícil dizer que essas bibliotecas realizam por completo o ideal local-first, e ainda há muito trabalho a fazer
- Os CRDTs têm potencial para se tornar a tecnologia de base de softwares colaborativos nos quais os usuários têm posse sobre seus dados, assim como o packet switching da internet ou a tela touchscreen capacitiva dos smartphones
Protótipos da Ink & Switch
- Embora tenha havido avanços acadêmicos na validação de algoritmos e teoria de CRDT, o uso industrial ainda é pequeno e ocorre majoritariamente em computação centrada no servidor
- Como exemplos de sistemas centrados no servidor que usam CRDT, são citados Azure Cosmos DB, Redis, Riak, Weave Mesh, SoundCloud Roshi e Facebook OpenR
- A Ink & Switch criou protótipos de apps colaborativos local-first para trabalho criativo que usam CRDT nos dispositivos finais dos usuários
- Os experimentos abordaram três perguntas
- Viabilidade técnica: quão perto os CRDTs estão de software real
- Experiência do usuário: é possível ter colaboração em tempo real como no Google Docs e colaboração assíncrona amigável ao offline como no Git sem um servidor central com autoridade
- Experiência do desenvolvedor: como uma camada de dados baseada em CRDT difere de um banco SQL, do sistema de arquivos e do Core Data
- Os três protótipos foram feitos com Electron, JavaScript e React, e considerou-se importante para a sensação de posse que fossem softwares que podem ser baixados e instalados
-
Trellis
- Trellis é um quadro Kanban modelado a partir do Trello
- Foi usado WebRTC em caráter experimental como camada de comunicação de rede
- Foi projetado um histórico de mudanças inspirado em Git e no “See New Changes” do Google Docs
- O usuário pode ver as tarefas do quadro Kanban e voltar para estados anteriores do documento
-
Pixelpusher
- Pixelpusher é um programa colaborativo de desenho que adiciona uma experiência de colaboração em tempo real ao estilo Figma ao Pixel Art to CSS, de Javier Valencia
- A comunicação de rede foi testada com a biblioteca P2P do projeto Dat
- Foram testados URL de compartilhamento de documento, branch/merge visual inspirado no Git, resolução de conflitos com destaque em vermelho para pixels em conflito e uma identificação básica de usuário baseada em avatares desenhados pelos próprios usuários
-
PushPin
- PushPin é um workspace de canvas de mídia mista parecido com Miro ou Milanote
- Como terceiro projeto baseado em Automerge, foi o mais completo dos três protótipos
- O uso real por equipes e usuários de teste externos gerou uma carga maior sobre a camada de dados subjacente
- Foram testados documentos compartilhados aninhados e conectados, vários renderizadores para documentos CRDT, um sistema de identidade mais avançado incluindo um modelo de outbox e compartilhamento de dados temporários como destaque de seleção
Resultados obtidos com os protótipos
- O objetivo dos três protótipos era avaliar a viabilidade técnica do software local-first e de CRDTs, a experiência do usuário e a experiência do desenvolvedor
- Cinco pessoas da equipe de desenvolvimento usaram regularmente, e testes individuais de usabilidade foram realizados com cerca de 10 usuários externos
- Os usuários externos incluíam designers profissionais, gerentes de produto e engenheiros de software
- Foi usada uma abordagem exploratória, e não uma metodologia formal de avaliação
-
A tecnologia CRDT funciona
- A confiabilidade do Automerge foi melhor do que o esperado
- Os desenvolvedores de aplicativos da equipe conseguiram integrar a biblioteca com relativa facilidade, e a mesclagem automática de dados quase sempre foi intuitiva e fluida
-
A experiência offline foi boa
- O fluxo de passar para o modo offline, trabalhar o quanto quisessem e depois reconectar para mesclar com as mudanças dos colegas funcionou bem
- Mesmo quando outros aplicativos exibiam avisos de “offline” e erros, bloqueando o trabalho, os protótipos local-first funcionavam normalmente independentemente do estado da rede
- Ao contrário de sistemas baseados em navegador, isso reduzia a insegurança sobre o aplicativo funcionar ou os dados estarem disponíveis, além de transmitir uma sensação de posse sobre as ferramentas e o trabalho produzido
-
Combina bem com o modelo FRP do React
- O modelo de Functional Reactive Programming do React combina bem com CRDTs
- Em uma camada de dados baseada em CRDT, o documento recebe ao mesmo tempo entradas locais do usuário e mudanças vindas de outros usuários e dispositivos pela rede
- O modelo FRP sincroniza de forma estável o estado visível da aplicação com o underlying state do documento compartilhado
- Os desenvolvedores se livram do trabalho incômodo de rastrear mudanças vindas de outros usuários e conciliá-las com a tela atual
- Se todas as mudanças de estado passarem por uma única função reducer, também fica fácil enviar as mudanças locais correspondentes para outros usuários
-
Os conflitos foram menos graves do que o esperado
- Os usuários raramente encontraram conflitos durante a colaboração, e mecanismos gerais de resolução funcionaram bem
- O Automerge rastreia mudanças em nível detalhado e considera a semântica dos tipos de dados
- Se dois usuários inserirem itens ao mesmo tempo na mesma posição de um array, os dois itens serão combinados em uma ordem determinística
- Um sistema de controle de versão de texto como o Git poderia ver isso como um conflito que exige resolução manual
- Como os usuários têm uma intuição sobre colaboração, às vezes dividem implicitamente suas áreas de trabalho para evitar editar a mesma seção ao mesmo tempo
- No aplicativo Kanban, se um usuário comenta em um cartão e outro move o cartão para outra coluna, as duas mudanças são refletidas
- Conflitos só acontecem quando a mesma propriedade do mesmo objeto é modificada ao mesmo tempo; o texto dá como exemplo dois usuários mudando simultaneamente a posição do mesmo objeto de imagem
- Nos protótipos, a semântica de mesclagem padrão do Automerge foi suficiente, e não foram encontrados casos que exigissem semântica personalizada
-
Visualizar o histórico do documento é importante
- Em sistemas colaborativos distribuídos, muitas mudanças de outros usuários podem chegar a qualquer momento
- Como um servidor central não medeia as mudanças, são necessárias ferramentas para entender o caminho pelo qual o documento chegou ao estado atual, quais versões existem e de onde vieram as contribuições
- O Trellis experimentou uma interface de “time travel” que permite ao usuário navegar e ver estados passados do documento mesclado
- Também foi testada uma abordagem de destacar automaticamente os elementos de mudança recém-recebidos
-
Compartilhar por URL é natural
- Entre vários mecanismos de compartilhamento de documentos, o modelo de URL inspirado na web foi o mais natural para usuários e desenvolvedores
- URLs podem ser copiadas e coladas, e compartilhadas por canais de comunicação como e-mail ou chat
- Permissões de acesso ao documento que vão além de URLs secretas ainda permanecem como uma questão de pesquisa em aberto
-
Sistemas P2P não se dividem simplesmente entre online e offline
- Sistemas centralizados geralmente definem os estados “up” ou “down” com base em haver ou não uma conexão estável com o servidor
- Em sistemas distribuídos, cada usuário pode ter uma perspectiva diferente conforme quais dados possui, compartilha e aceita
- Edições feitas em um laptop dentro de um avião podem ser distribuídas a outros usuários depois do pouso, quando houver conexão
- Outros usuários podem aceitar em sua versão do documento todas essas mudanças, apenas parte delas ou nenhuma
- Como em um repositório Git, o “master” de um determinado usuário passa a ser função do momento em que ele se comunicou pela última vez com outros usuários
- Documentos distribuídos dão aos usuários controle sobre os dados, mas o que isso significa na prática do ponto de vista da UI ainda exige mais pesquisa
-
Históricos longos de mudanças criam problemas de desempenho
- Quando o PushPin foi usado em documentos reais, como planejamento de sprint, desempenho e uso de memória e disco rapidamente se tornaram problemas
- CRDTs armazenam o histórico completo, inclusive de edição de texto em nível de caractere
- Como alguém pode se reconectar ao documento seis meses depois e precisar mesclar as mudanças a partir daquele ponto, não é fácil simplesmente truncar o histórico
- A otimização do Automerge continua em andamento e segue sendo uma das principais áreas de trabalho
-
A comunicação em rede ainda não está resolvida
- Os algoritmos CRDT tratam apenas da mesclagem de dados; eles não tratam de como as edições de outros usuários chegam fisicamente ao mesmo computador
- Nos experimentos, foram testados WebRTC, uma implementação de sneakernet que copia arquivos via Dropbox e chave USB, a possibilidade do protocolo IPFS e a biblioteca P2P Hypercore, da Dat
- CRDTs não exigem necessariamente uma camada de rede P2P; a comunicação via servidor também é possível
- Para concretizar plenamente o objetivo de longevidade do local-first, uma solução descentralizada que sobreviva por mais tempo que serviços de backend de fornecedores é o objetivo lógico final
- As tecnologias P2P não estavam prontas para produção e, em especial, o NAT traversal tinha baixa confiabilidade dependendo do roteador ou da topologia da rede
- A experiência de colaboração em tempo real diretamente entre computadores, sem acesso à internet, mostra um grande potencial em um mundo dependente de APIs centrais
-
Servidores em nuvem permanecem em papel auxiliar
- Protótipos de colaboração em tempo real como o PushPin conseguem compartilhar documentos sem servidor intermediário, o que é bom para privacidade e propriedade
- No entanto, se um usuário fechar o laptop depois de compartilhar um documento, antes que a outra pessoa se conecte, os dois usuários não conseguirão se conectar porque não estarão online ao mesmo tempo
- Em um mundo local-first, o servidor pode atuar não como autoridade central, mas como um cloud peer
- Armazenar uma cópia do documento e entregá-la quando outro peer ficar online
- Fornecer um local para arquivamento e backup
- Fazer a ponte com APIs de servidor tradicionais, como previsão do tempo ou cotações de ações
- Oferecer burst computing, como renderização de vídeo com GPUs potentes
- A diferença entre sistemas tradicionais e sistemas local-first não está na existência de um servidor, mas no fato de que o servidor não é a fonte da verdade e assume um papel de suporte
Trabalhos necessários daqui para frente
-
Pesquisadores de sistemas distribuídos e linguagens de programação
- A pesquisa em CRDTs e tecnologias P2P pode contribuir muito para o software local-first
- Hoje, a pesquisa em CRDTs geralmente assume um modelo em que todos os colaboradores aplicam imediatamente as edições a uma única versão do documento
- Na prática, apps local-first precisam poder rejeitar edições de outros colaboradores ou criar alterações privadas em versões de documento que não são compartilhadas
- Falta pesquisa que amplie conceitos de controle de versão distribuído, como branch, fork e rebase, para modelos de colaboração em que várias versões de documentos e branches coexistem lado a lado
- Tipos, migração de esquema e compatibilidade também são questões importantes
- Cada colaborador pode usar versões e recursos diferentes do app
- Como não há um servidor central de banco de dados, não existe um esquema “atual” autoritativo dos dados
- Diferentes versões do app precisam interoperar com segurança enquanto o formato dos dados evolui
-
Pesquisadores de IHC
- Em sistemas centralizados, há muitos exemplos de exibição do estado de sincronização com o servidor, mas sistemas descentralizados trazem novos problemas de UI
- É necessário pesquisar como comunicar estados online·offline e disponível·indisponível em sistemas nos quais cada usuário pode ter uma cópia diferente dos dados
- Quando é possível colaborar diretamente com outros nós sem a internet ampla, o significado de “online” também muda
- Como todos os documentos podem ganhar um histórico de versões complexo apenas com o uso cotidiano, são necessárias UIs que ajudem o usuário a entender versões, aceitação de mudanças e o processo de formação do documento
- Hoje, o gerenciamento de mudanças é dominado pelo modelo diff·patch típico de código-fonte e pelo modelo de suggestion·comment do Google Docs
- Continua em aberto como generalizar essas ideias para formatos de dados que não sejam texto
- No local-first, não é possível impedir que o usuário que possui os dados os modifique localmente, e o conceito de permissão muda para algo em que outros usuários escolhem se querem assinar essas mudanças
-
Profissionais da prática
- Engenheiros, designers, gerentes de produto e desenvolvedores independentes que criam software de produção podem adotar passos graduais rumo a um futuro local-first
- Para apps rápidos, é possível reduzir spinners ao abrir documentos com cache agressivo e pré-download, e confiar por padrão no cache local
- O suporte a múltiplos dispositivos pode ser implementado com relativa facilidade por meio de infraestruturas de sincronização como Firebase e iCloud, mas há preocupações com longevidade e privacidade
- Para offline, na web, Progressive Web Apps, Service Workers e app manifest podem ajudar
- Testes de app podem ser feitos desligando o Wi-Fi ou alterando as condições de rede com ferramentas como o simulador de network conditions do Chrome DevTools e o iOS Network Link Conditioner
- Para colaboração, além de CRDTs, o Operational Transformation implementado em ShareDB e outros é uma tecnologia mais estabelecida
- Para preservação de longo prazo, deve ser possível exportar facilmente em formatos estáveis, como JSON e PDF
- Exportação em massa como no Google Takeout
- Backup contínuo em formato de arquivo estável no GoodNotes
- Download de documentos JSON no Trello
- Em termos de privacidade, é preciso deixar claro ao usuário se os dados ficam armazenados apenas no dispositivo ou se são enviados ao backend
- Para dar controle ao usuário, deve ser fácil fazer backup, duplicar e excluir documentos dentro do app, e é citado o caso do Google Docs, que reimplementou operações básicas de sistema de arquivos por meio do Google Drive
Oportunidades para startups e conclusão
- Para fundadores que querem criar infraestrutura para desenvolvedores, “Firebase for CRDTs” é apresentado como uma oportunidade de mercado interessante
- Uma startup desse tipo precisa oferecer uma boa experiência para desenvolvedores e bibliotecas de persistência local como SQLite ou Realm
- Deve oferecer suporte a iOS, Android, Windows, Mac, Linux, Electron e Progressive Web Apps
- Controle do usuário, privacidade, suporte a múltiplos dispositivos e colaboração devem vir incluídos por padrão
- O teste decisivo de sucesso é se o app do cliente continua funcionando para sempre mesmo que todos os servidores sejam desligados
- O software em nuvem trouxe colaboração e apps sempre atualizados acessíveis de qualquer lugar, mas, ao deixar a propriedade dos dados no servidor, transformou o usuário em uma espécie de inquilino dos próprios dados
- A abordagem local-first mostra que os usuários podem manter a propriedade e o controle dos próprios dados e, ainda assim, obter colaboração e acessibilidade no estilo da nuvem
- Para uma implementação real, ainda são necessários mais suporte offline, melhor aproveitamento do armazenamento on-device, melhorias em algoritmos, modelos de programação e interfaces de usuário, além da transformação de CRDTs e redes P2P em produtos
1 comentários
Opiniões no Hacker News
Concordo totalmente. Estou cansado dessa tendência em que todos os serviços levam meus dados para a nuvem deles e me fazem pagar uma assinatura para usar direito
O app de acompanhamento fitness que estou criando pretende seguir o modelo “compre uma vez, receba atualizações por X anos, sincronize com todos os dispositivos e continue usando para sempre depois disso”. Se precisar de atualizações depois de X anos, você compra a nova versão de novo; se os recursos atuais forem suficientes, continua usando
Eu gostaria que a maior parte dos softwares pudesse ser comprada assim, por um preço justo, que o produto em si fosse bom e que não ficasse preso a ponto de ser inutilizável sem a nuvem. O melhor do software local-first é que ele restaura um incentivo saudável de cobrar pela qualidade do produto, em vez de anúncios, rastreamento e maximização de engajamento
Todas as notas são arquivos Markdown, então o próprio cliente também se torna opcional
Também é preciso manter os servidores de sincronização funcionando continuamente e considerar casos em que usuários sincronizem, de uma vez só, um ano inteiro de dados em um dia. Como também é preciso continuar pagando as pessoas que cuidarão do desenvolvimento futuro, há aspectos que ficam de fora se a análise for feita apenas do ponto de vista do desenvolvedor
https://rodyne.com/?p=1439
O IDE de notas/tarefas que estamos criando também segue essa abordagem: https://thymer.com/local-first-ejectable
Em Berlim há a Local-first Software Conference anual, organizada pela Ink and Switch, e em novembro deste ano também haverá em SF um evento derivado chamado Sync Conf
https://www.localfirstconf.com/
https://syncconf.dev/
Neste ano, foi bom o painel em que coautores do artigo original falaram sobre o que é software local-first no contexto de ferramentas de desenvolvimento e o que aprenderam desde o artigo original: https://youtu.be/86NmEerklTs?si=Kodd7kD39337CTbf
A comunidade está se consolidando em torno da visão de que “sincronização” é um componente do local-first, mas uma tecnologia aplicável de forma muito mais ampla. Local-first é uma característica de software para usuários finais, enquanto ferramentas de desenvolvimento como motores de sincronização são ferramentas que o viabilizam, e não necessariamente local-first por si só
Todas as palestras dos últimos anos estão aqui: https://youtube.com/@localfirstconf?si=uHHi5Tsy60ewhQTQ
É um momento interessante para a comunidade de local-first/motores de sincronização. Temos criado ferramentas que viabilizam experiências de colaboração em tempo real e assíncrona, e, com a chegada da IA, esse mercado está crescendo. Todo app de IA é, em essência, um sistema colaborativo multiusuário em que agentes participam como atores, então precisa das tecnologias com as quais a comunidade de motores de sincronização vem trabalhando
https://www.localfirst.fm/
Vale a leitura, e já houve várias discussões ativas no passado
https://news.ycombinator.com/item?id=19804478 - maio de 2019, 191 comentários
https://news.ycombinator.com/item?id=21581444 - novembro de 2019, 241 comentários
https://news.ycombinator.com/item?id=23985816 - julho de 2020, 9 comentários
https://news.ycombinator.com/item?id=24027663 - agosto de 2020, 134 comentários
https://news.ycombinator.com/item?id=26266881 - fevereiro de 2021, 90 comentários
https://news.ycombinator.com/item?id=31594613 - junho de 2022, 30 comentários
https://news.ycombinator.com/item?id=37743517 - outubro de 2023, 50 comentários
Qualquer coisa que tenha dependência online inevitavelmente exige manutenção contínua e gera custos. Se um sistema não for local-first, ou de preferência apenas local, ele não foi projetado para confiabilidade de longo prazo
Eletrodomésticos e carros conectados chegam perto de ser a engenharia mais idiota do ponto de vista prático
Empresas que obtêm receita de assinaturas têm mais faturamento e valuations mais altos, conseguem captar mais recursos com facilidade e vencem empresas que não seguem esse modelo. Por causa dessa estrutura de autorreforço, considero que o software local-first morreu
A Cloudflare oferece hospedagem de arquivos estáticos quase de graça, e o custo fica perto de um erro de arredondamento. Mesmo que 1000 apps local-first sincronizem com o Dropbox, poderiam funcionar com um armazenamento de US$ 10 por mês. Esse armazenamento não é uma ferramenta primitiva de baixo nível como S3, mas um serviço para consumidores com autenticação, suporte e até programa de sincronização. A maior parte dos custos de cloud, na verdade, não é necessária
Ninguém obriga os jogos a dependerem apenas de serviços online. Não é uma exigência legal nem regulatória. Como muitas coisas em software, é apenas uma escolha. Escolher depender de serviços online e depois dizer “vai custar dinheiro desfazer isso” é míope, patético e não deve ser aceito
Mais apps deveriam ser local-first. Se o usuário não quiser sincronizar seus dados com a cloud, essa opção deveria existir
Há algum tempo venho criando o Brisqi, um app offline-first ou local-first, e desde o início ele foi projetado com a filosofia offline-first
https://brisqi.com
Apps local-first devem ser projetados para funcionar de forma totalmente offline por tempo indefinido. A experiência local é a base, não um plano B, e a sincronização com a cloud deve ser um recurso auxiliar, não um requisito
Não considero apps que dependem de cache temporário como offline-first. Um app realmente offline-first deve persistir os dados em um banco de dados local. Muitos apps que se dizem “offline-first” na prática oferecem apenas funcionalidade offline limitada e acabam sendo mais offline-tolerant, dependendo de uma reconexão à internet
Apps offline-first são claramente mais difíceis de criar do que web apps exclusivamente online, e o mecanismo de sincronização precisa ser confiável o suficiente para garantir que, durante a transição entre offline/online, os dados sejam sincronizados de forma consistente com a cloud e não sejam perdidos. Escrevi mais sobre a abordagem no blog: https://blog.brisqi.com/posts/how-i-designed-an-offline-first-app-an-outline
É interessante ver esse princípio explicado para o mercado consumidor, mas atualmente estamos fazendo a mesma coisa no lado de ativos industriais/dados industriais
Em www.sentineldevices.com, todo o aprendizado, a análise e a tomada de decisão acontecem no equipamento do cliente. Não há sequer um servidor para enviar dados; é um modelo em que, explicitamente, tudo roda dentro do dispositivo
Em SCADA/automação industrial, há muitos casos de uso em que os dados não podem ser levados para fora. Empresas de dados/IA ignoram uma enorme base de clientes e casos de uso porque é difícil prestar serviço onde o cliente está e, em vez disso, querem trazer os dados para si e manter o lock-in do fornecedor
Ao conversar com clientes, na verdade precisamos enfatizar muito: “não, isto é local e não há conexão externa”. Como eles quase nunca ouviram algo assim, muitas vezes é preciso explicar passo a passo para que entendam que tudo acontece localmente, e fornecedores de software não costumam assimilar bem esse conceito. Seria bom se o software local-first se consolidasse mais no mercado consumidor, para que isso também se tornasse familiar no setor industrial
“Opere sua fábrica pelo smartphone!” — agora basta um zero-day para que um script kiddie possa brincar com as minhas bombas
Olhando a página de carreiras, vi que todas as vagas são presenciais; fiquei curioso se isso se deve a uma limitação de precisar estar frente a frente para criar software local-first, ou se é principalmente por motivos de gestão
Pessoalmente, não concordo com essa abordagem. Parece uma tentativa de resolver o problema de negócios de “não se pode confiar nos provedores de nuvem” por meio do compromisso técnico de “evitar arquiteturas centralizadas”.
A falta de controle e de confiabilidade do software fechado foi resolvida com novos modelos de negócios, como o desenvolvimento open source, novas licenças e formas de receita como contratos de manutenção em vez de custos de licença.
Da mesma forma, os problemas dos provedores de nuvem também precisam de soluções no nível do modelo de negócios. Por exemplo, seria possível criar contratos/licenças padrão que definam direitos para que os usuários possam confiar na relação com o provedor de nuvem. Com o tempo, usuários poderiam passar a fazer negócios apenas com provedores que tenham essas licenças.
Isso poderia incluir cláusulas como acordos de fim de vida, garantias de portabilidade de dados e transparência de privacidade de dados, auditando o acesso aos dados e informando quem/o quê/quando os leu. O problema é a adoção. O ponto central é por que os provedores de nuvem aceitariam isso; se temerem churn, poderiam oferecer esses contratos apenas em assinaturas anuais ou cobrar mais caro.
A criptografia ao usar serviços de nuvem é um bom exemplo. Tentar proteger dados com políticas de privacidade e regras burocráticas é quase inútil. Dados têm valor, é difícil para clientes ou governos saberem se uma empresa os está vendendo às escondidas, e também é difícil saber, antes que seja tarde demais, se ela economizou em segurança.
Mas, se for possível provar matematicamente que os dados são criptografados no dispositivo do cliente e que o servidor não consegue acessar o texto em claro, não é preciso se preocupar com isso. O problema é quando o servidor não apenas armazena os dados, mas precisa processá-los; nesse caso, a solução técnica passa a ser usar o próprio servidor.
Sem criar um app por conta própria, ou sem que alguém gentil o crie, é difícil aproveitar isso. É melhor do que nada, mas não tão bom quanto um app local capaz de continuar rodando por anos ou décadas depois que a empresa fecha as portas ou interrompe o suporte.
Em finanças, recuperar corresponderia a receber dinheiro ou bens; na nuvem, poderia significar receber um grande arquivo Zip com todo o conteúdo da conta.
Mas receber a entrega nem sempre é prático ou desejável. Em finanças, é possível transferir uma conta para outra instituição; em serviços de nuvem, em muitos casos a transferência da conta provavelmente seria muito mais útil.
A dificuldade aqui é a portabilidade. Mesmo definindo bem os direitos de propriedade e os direitos do usuário sobre uma conta na nuvem, fica ambíguo o que significa receber os amigos do Facebook, ou o que significa transferir uma conta do Facebook para outro lugar.
Esse problema exige tanto soluções de negócios quanto soluções técnicas, e o artigo propõe quais características uma solução deveria ter.
Também não é correto dizer que local-first defende descentralização. Martin Kleppmann afirmou explicitamente que não vê tecnologias descentralizadas resolvendo esse problema de uma forma que chegue ao mercado de massa. Ele defende um mecanismo de sincronização padronizado e centralizado que viabilize o ideal local-first.
Veja a palestra da Local-first conf do ano passado: https://youtu.be/NMq0vncHJvU?si=ilsQqIAncq0sBW95
Em uma situação de crise, dá para fazer em algumas semanas, mas pode ficar muito bagunçado. Mesmo ao migrar entre bancos de dados open source na mesma versão, há muitas diferenças entre serviços de nuvem, então acontece o mesmo.
A melhor solução é manter os dados no seu próprio ambiente desde o início e cortar a conexão se necessário. Isso é possível combinando gerenciamento BYOC e open source. Nossa empresa também opera produtos de dados BYOC, então temos interesse econômico nessa abordagem, mas sei que é possível porque vi isso funcionando.
Com meus projetos https://github.com/ibizaman/selfhostblocks e https://github.com/ibizaman/skarabox, estou tentando tornar exatamente isso amplamente possível
O objetivo comum é tornar a auto-hospedagem mais acessível ao público em geral
Com base no NixOS, tento oferecer https, SSO, LDAP, backups, ZFS com snapshots etc. prontos por padrão, de forma o mais declarativa possível
Como empacota Vaultwarden e Nextcloud, dá para armazenar a maior parte dos dados, então é um concorrente da hospedagem em nuvem, e também oferece serviços como o Home Assistant
Também é concorrente do YUNoHost, mas o SelfHostBlocks permite auto-hospedar diretamente os pacotes que você quiser com os componentes que ele oferece, então é melhor — ou tenta ser. É mais próximo de uma biblioteca do que de um framework
Também concorre com NAS, mas considero melhor pelo fato de tudo ser open source. Por enquanto, o usuário ainda precisa ser técnico, mas estou removendo essa limitação, e um dos objetivos é permitir instalar no próprio hardware sem precisar conhecer Nix nem mexer na linha de comando
Boa parte dos apps auto-hospedáveis são aplicações web com banco de dados, servidor e front-end, mas, em muitos casos de uso, a pessoa só usa em um computador e não precisa de uma versão hospedada nem de sincronização com outros dispositivos. Por exemplo, contabilidade pessoal dá para fazer no computador uma vez por mês, então não há necessidade de manter uma aplicação web rodando 24 horas por dia em algum lugar. Basta abrir o programa, trabalhar e fechar
Há uma grande discrepância entre a quantidade de alternativas livres e open source auto-hospedáveis de alta qualidade e o número de pessoas que de fato conseguem usá-las. Precisamos de mais projetos que reduzam essa lacuna. Pretendo testar o selfhostblocks para algumas coisas e tentar contribuir
Não há motivo para todo aplicativo ter sua própria plataforma de sincronização. Esse enquadramento parece vir dos apps móveis, que não têm composição nem modularidade entre programas
Se levarmos “local-first” a sério, basta usar o sistema de arquivos, e o usuário pode escolher entre várias soluções, como git, Box etc.
Exigir uma assinatura de sincronização própria é tão desagradável quanto qualquer outro SaaS — e, na verdade, é mais opaco e frágil
Primeiro, eu também quero local-first, mas também quero concorrência. Se fosse apenas local-first simples, qualquer sincronização serviria, mas quero algo além disso. Quero que funcione de forma fluida, sem eu precisar me preocupar, como o Dropbox, e que, mesmo em áreas sem comunicação, eu e minha esposa possamos editar separadamente em nossos celulares
Segundo, a sincronização funciona muito melhor quando conhece profundamente a estrutura dos dados e sua semântica. git e Box têm limitações consideráveis, e essas limitações aumentam ainda mais quando há requisitos de concorrência
Em teoria, gosto da abordagem local-first de desenvolvimento. Ela combina bem com a filosofia de small tech, que trata privacidade e propriedade dos dados como princípios básicos
Mas, na prática, é difícil. Na verdade, você precisa criar um mecanismo de sincronização, lidar com resolução de conflitos e gerenciar migrações de esquema
Ainda assim, parece que as ferramentas de desenvolvimento para software local-first melhoraram nos últimos anos. Tenho acompanhado jazz.tools, electric-sql e Zero, da Rocicorp, e fico curioso para saber se há outras
https://couchdb.apache.org/
https://pouchdb.com/
Mais reflexões sobre o desenvolvimento de aplicações local-first de cerca de 10 anos atrás também podem ser vistas aqui: https://unhosted.org/
Preciso escrever um post no blog, mas antes eu tinha pesquisado PowerSync, electricSQL, LiveStore e PowerSync, e também dei uma olhada rápida no jazz.tools, mas queria algo mais estruturado
Até agora, estou bem impressionado. Estou escrevendo com Vue e uma biblioteca da comunidade; as permissões foram um pouco complicadas, mas ficaram simples depois que entendi. Também gosto do login por e-mail mágico e dos recursos de dashboard/respostas, embora pareça que algumas mudanças grandes sejam necessárias para tornar tudo menos trabalhoso
Gosto do fato de ser open source e de poder fazer self-hosting se quiser. O jazz não tinha estrutura suficiente, e no LiveStore o event store parecia trabalhoso demais, embora tivesse seu apelo. Foi uma pena as ferramentas de desenvolvimento ficarem atrás de um paywall, mas dá para entender. O electricSQL oferecia metade da solução, isto é, só leitura, e faltava um modelo de escrita. CouchDB/PouchDB também não tinham estrutura suficiente para mim, e eu queria que o suporte entre documentos viesse integrado de forma mais clara. Não investiguei o Zero direito
Na verdade, eu queria apontar para o link “landscape” no menu superior, mas a URL é bem inconveniente
https://automerge.org/
Há implementações em Rust e JavaScript, e ele também oferece algumas estratégias de rede. Não vem acompanhado de um pacote de produtos gratuito/pago como o jazz.tools, mas é bem bom
https://www.ditto.com
É uma plataforma local-first com suporte a sincronização em tempo real, tendo CRDTs como núcleo, o que torna muito mais fácil gerenciar a resolução de conflitos. Foi projetada para lidar nativamente com casos de uso offline-first e sincronização peer-to-peer, então você não precisa criar um mecanismo de sincronização do zero
Suporta diversas plataformas, incluindo Swift, Kotlin(Android), Flutter/Dart, React Native, JavaScript(Web/Node), .NET(C#), C++, Java e Rust. A documentação pode ser vista aqui: https://docs.ditto.live/home/about-ditto