excache

Uno strato di cache in Elixir, basato sul modello ad attori OTP. Concorrente, resistente ai guasti di singoli processi, con test reali.

excache
TL;DR

Uno strato di cache in Elixir sul modello ad attori OTP. Concorrenza senza corse, resilienza ai guasti di un singolo processo e test veri. Il trucco sta nell'assicurarsi che la caduta di un elemento non trascini il resto.

Introduzione

Una cache condivisa tra molti thread è uno dei classici problemi difficili di concorrenza. excache mostra che Elixir e il modello ad attori OTP trasformano quel problema in qualcosa che si può gestire senza lock e senza la sorda paura del deadlock. Invece di lottare contro la memoria condivisa, sposti lo stato dove nessuno vi accede in parallelo.

È un progetto su due proprietà insieme: concorrenza senza corse e resilienza ai guasti. Entrambe scaturiscono dalla stessa filosofia OTP, in cui lo stato vive in un processo e gli errori non vengono nascosti sotto il tappeto ma isolati.

Il modello ad attori rovescia il problema della concorrenza

Nella maggior parte dei linguaggi una cache condivisa tra thread significa lock, mutex e la sorda paura del deadlock. Elixir procede in altro modo: ogni stato vive dentro un processo che gestisce un messaggio alla volta. Invece di bloccare la memoria condivisa, invii un messaggio e ricevi una risposta.

La corsa sulla struttura dati semplicemente non esiste, perché nessuno vi accede in parallelo. La stessa garanzia che in altri linguaggi bisogna strappare con i mutex qui è una proprietà gratuita del modello.

cache.ex · bash
def handle_call({:get, key}, _from, state) do
  {:reply, Map.get(state, key), state}
end

Let it crash invece della difesa

In OTP non avvolgi ogni operazione in un blocco difensivo contro il guasto. Invece lasci che il processo si schianti, e un albero di supervisione lo rialza in uno stato pulito. È l'opposto della programmazione difensiva: non nascondi l'errore, lo lasci rovesciare un processo e ti fidi che la supervisione lo ricostruisca.

excache si appoggia direttamente a questo: la morte di un processo di cache non rovescia l'intero strato, perché gli altri processi vivono in modo indipendente. Lo stato corrotto svanisce con il processo, e il suo successore parte pulito invece di trascinarsi dietro dati rotti.

➜
Suggerimento

Il test di questa proprietà consiste nell'uccidere deliberatamente un processo nel pieno del traffico e verificare che lo strato risponda ancora. Se l'intera cache cade con un solo processo, l'albero di supervisione è assemblato male, e un buon test lo intercetta subito.

Questo è un test controfattuale nella sua forma più pura: non verifichi che il sistema funzioni quando tutto va bene, ma che sopravviva al guasto che deve sopravvivere. Un test che non vede mai morire un processo non dimostra alcuna resilienza.

La resilienza come proprietà, non come toppa

Il risultato è uno strato che tratta il guasto come un normale stato operativo, non come un'eccezione da rattoppare. La concorrenza è sicura per progetto, perché nessuno condivide la memoria, e un singolo guasto resta locale, perché la supervisione ricostruisce solo ciò che è caduto.

Le proprietà dello strato e da cosa scaturiscono

ProprietàDa cosa scaturisce
Nessuna corsaun processo, un messaggio alla volta
Nessun lockcomunicazione tramite messaggi
Isolamento dei guastistato racchiuso in un processo
Ritorno a uno stato pulitol'albero di supervisione

Altri progetti

Altri lavori della stessa categoria - scopri come affrontiamo sfide simili.

Hai un progetto simile?

Contattaci - il preventivo è gratuito e arriva entro un'ora.