Descrição
Todas as operações de mutação do Engine (set, put_cf, delete, delete_cf) exigem &mut self, mas o estado mutável já está atrás de Arc<Mutex<EngineCore>>. Isso torna o Engine impossível de usar concorrentemente com Arc<Engine> — obrigando o usuário a envolver o Engine em um Mutex externo adicional, criando contenção desnecessária.
Localização
Arquivo: src/core/engine/mod.rs
pub struct Engine<C: Cache> {
options: EngineOptions,
core: Arc<Mutex<EngineCore<C>>>, // ← estado mutável já sincronizado
compaction_running: Arc<AtomicBool>,
compaction_thread: Mutex<Option<JoinHandle<()>>>,
_manifest: PathBuf,
_sst_dir: PathBuf,
}
impl<C: Cache> Engine<C> {
pub fn put_cf(&mut self, cf: &str, key: Vec<u8>, value: Vec<u8>) -> Result<()> {
// ↑ &mut self desnecessário — core já é Mutex
let mut core = self.core.lock().map_err(...)?;
// ...
}
}
Problema
Engine já usa Arc<Mutex<EngineCore>> internamente — toda a mutabilidade está protegida
put_cf, delete, set, delete_cf, flush_memtable, compact tomam &mut self
get, get_cf, scan, scan_cf, stats tomam &self (consistentes)
- Num servidor HTTP (actix-web), o Engine precisa ser compartilhado entre threads:
// Hoje o usuário precisa fazer:
let engine = Arc::new(Mutex::new(Engine::new_from_config(...)));
// Mutex DUPLICADO — engine já tem Mutex interno!
Impacto em Produção
- Concorrência limitada:
Arc<Mutex<Engine>> serializa TODAS as operações no mutex externo, impedindo leitura concorrente durante escritas
- Perda de performance: leituras (
get, scan) que poderiam ser concorrentes ficam serializadas
- Padrão não-idiomático: databases Rust (sled, rocksdb) expõem
&self para todas as ops
- Problema com actix-web: o padrão
web::Data<Arc<Engine>> não funciona
Proposta
- Mudar todas as operações de escrita para
&self
- Usar
Mutex interno do EngineCore para sincronização já existente
- Operações de leitura (
get, scan, stats) não precisam de mudança (já são &self)
close() e drop() precisam de atenção — close() já é &self ✅
flush_memtable() também muda para &self
- Verificar se há campos mutáveis fora do
EngineCore:
options: pode ser imutável após construção
_manifest, _sst_dir: apenas usados na inicialização (podem ser movidos para EngineCore ou tornados imutáveis)
compaction_thread: já é Mutex<Option<...>> — precisa de &self access
Critérios de Aceite
Descrição
Todas as operações de mutação do
Engine(set,put_cf,delete,delete_cf) exigem&mut self, mas o estado mutável já está atrás deArc<Mutex<EngineCore>>. Isso torna o Engine impossível de usar concorrentemente comArc<Engine>— obrigando o usuário a envolver o Engine em umMutexexterno adicional, criando contenção desnecessária.Localização
Arquivo:
src/core/engine/mod.rsProblema
Enginejá usaArc<Mutex<EngineCore>>internamente — toda a mutabilidade está protegidaput_cf,delete,set,delete_cf,flush_memtable,compacttomam&mut selfget,get_cf,scan,scan_cf,statstomam&self(consistentes)Impacto em Produção
Arc<Mutex<Engine>>serializa TODAS as operações no mutex externo, impedindo leitura concorrente durante escritasget,scan) que poderiam ser concorrentes ficam serializadas&selfpara todas as opsweb::Data<Arc<Engine>>não funcionaProposta
&selfMutexinterno doEngineCorepara sincronização já existenteget,scan,stats) não precisam de mudança (já são&self)close()edrop()precisam de atenção —close()já é&self✅flush_memtable()também muda para&selfEngineCore:options: pode ser imutável após construção_manifest,_sst_dir: apenas usados na inicialização (podem ser movidos para EngineCore ou tornados imutáveis)compaction_thread: já éMutex<Option<...>>— precisa de&selfaccessCritérios de Aceite
Engine::put_cf()aceita&selfEngine::set()aceita&selfEngine::delete_cf()aceita&selfEngine::delete()aceita&selfEngine::flush_memtable()aceita&selfEngine::compact()aceita&selfEngine::compact_cf()aceita&selfweb::Data<Arc<Engine>>no actix-webget()simultaneamente)cargo test --all-featurespassacargo clippy -- -D warningspassa