Tesseras

Fase 4: Tuning de Performance

2026-02-15

Uma rede P2P que atravessa NATs mas engasga com seu proprio I/O nao serve de muito. A Fase 4 continua com tuning de performance: centralizacao da configuracao do banco de dados, cache de blobs de fragmentos em memoria, gerenciamento de ciclo de vida de conexoes QUIC e eliminacao de leituras desnecessarias de disco no hot path de atestacao.

O principio orientador foi o mesmo do resto do Tesseras: fazer a coisa mais simples que realmente funciona. Sem alocadores customizados, sem estruturas de dados lock-free, sem complexidade prematura. Um StorageConfig centralizado, um cache LRU, um reaper de conexoes e uma correcao pontual para evitar reler blobs que ja tinham checksum calculado.

O que foi construido

Configuracao SQLite centralizada (tesseras-storage/src/database.rs) — Um novo struct StorageConfig e funcoes open_database() / open_in_memory() que aplicam todos os pragmas SQLite em um unico lugar: journal mode WAL, foreign keys, modo synchronous (NORMAL por padrao, FULL para hardware instavel como RPi + cartao SD), busy timeout, tamanho do cache de paginas e intervalo de autocheckpoint WAL. Anteriormente, cada ponto de chamada abria uma conexao e aplicava pragmas ad hoc. Agora o daemon, CLI e testes passam todos pelo mesmo caminho. 7 testes cobrindo foreign keys, busy timeout, journal mode, migracoes, modos synchronous e criacao de arquivos WAL em disco.

Cache LRU de fragmentos (tesseras-storage/src/cache.rs) — Um CachedFragmentStore que envolve qualquer FragmentStore com um cache LRU ciente de bytes. Blobs de fragmentos sao cacheados na leitura e invalidados na escrita ou exclusao. Quando o cache excede seu limite de bytes configurado, as entradas menos recentemente usadas sao removidas. O cache e transparente: ele proprio implementa FragmentStore, entao o resto da pilha nao sabe que esta la. Metricas Prometheus opcionais rastreiam hits, misses e uso atual de bytes. 3 testes: hit no cache evita leitura interna, store invalida cache, remocao quando excede bytes maximos.

Metricas Prometheus de storage (tesseras-storage/src/metrics.rs) — Um struct StorageMetrics com tres contadores/gauges: fragment_cache_hits, fragment_cache_misses e fragment_cache_bytes. Registrado no registry Prometheus e conectado ao cache de fragmentos via with_metrics().

Correcao do hot path de atestacao (tesseras-replication/src/service.rs) — O fluxo de atestacao anteriormente lia cada blob de fragmento do disco e recalculava seu checksum BLAKE3. Como list_fragments() ja retorna FragmentId com um checksum armazenado, a correcao e trivial: usar frag.checksum ao inves de blake3::hash(&data). Isso elimina uma leitura de disco por fragmento durante atestacao — para uma tessera com 100 fragmentos, sao 100 leituras a menos. Um teste com expect_read_fragment().never() verifica que nenhuma leitura de blob acontece durante atestacao.

Ciclo de vida do pool de conexoes QUIC (tesseras-net/src/quinn_transport.rs) — Um struct PoolConfig controlando maximo de conexoes, timeout de inatividade e intervalo do reaper. PooledConnection envolve cada quinn::Connection com um timestamp last_used. Quando o pool atinge capacidade maxima, a conexao inativa mais antiga e removida antes de abrir uma nova. Uma tarefa reaper em background (Tokio spawn) periodicamente fecha conexoes que ficaram inativas alem do timeout. 4 novas metricas de pool: tesseras_conn_pool_size, pool_hits_total, pool_misses_total, pool_evictions_total.

Integracao no daemon (tesd/src/config.rs, main.rs) — Uma nova secao [performance] na configuracao TOML com campos para tamanho de cache SQLite, modo synchronous, busy timeout, tamanho de cache de fragmentos, maximo de conexoes, timeout de inatividade e intervalo do reaper. O main() do daemon agora chama open_database() com o StorageConfig configurado, envolve FsFragmentStore com CachedFragmentStore e vincula QUIC com o PoolConfig configurado. A dependencia direta de rusqlite foi removida do crate do daemon.

Migracao do CLI (tesseras-cli/src/commands/init.rs, create.rs) — Ambos os comandos init e create agora usam tesseras_storage::open_database() com o StorageConfig padrao ao inves de abrir conexoes rusqlite diretamente. A dependencia de rusqlite foi removida do crate do CLI.

Decisoes de arquitetura

O que vem a seguir

Com tuning de performance implementado, Tesseras lida com o caso comum de forma eficiente: leituras de fragmentos acertam o cache LRU, atestacao pula I/O de disco, conexoes QUIC inativas sao removidas automaticamente e o SQLite e configurado consistentemente em toda a pilha. Os proximos passos focam em funcionalidades criptograficas (Shamir, time-lock) e hardening para implantacao em producao.