Penso che la tua domanda non sia specifica di Akka.NET in esclusiva. Quindi risponderò allo sviluppo di Akka / Scala.
0 Non tutto è un attore. Le funzioni sono ancora funzioni con tutta quella composizione funzionale e purezza.
- Il modello di attore diventa molto utile quando ti estendi oltre il CRUD nella terra del Domain-Driven-Design e dell'architettura esagonale.
- Non posso dirlo per .NET, ma nel mondo JVM la maggior parte delle chiamate al database (JDBC) stanno bloccando. Nel frattempo, il sistema degli attori di solito funziona su un pool di thread limitato rispetto alle dimensioni del numero dei core della CPU. Quindi, se il sistema dell'attore funziona con il blocco delle chiamate, Akka consente di configurare un pool di thread separato per quel sottosistema, ovvero la sottostruttura dell'albero di supervisione del sistema dell'attore. Quindi puoi lasciare il tuo core aziendale non bloccante con 4 thread e dare 200 thread al sottosistema di archiviazione.
- Le strutture di dati immutabili (persistenti, funzionali) sono la chiave. Non hai bisogno di sincronizzazione per usarli. Anche se a volte potresti dover passare un riferimento ad es. Bytestream. Bene, dovresti controllare che il mittente non tenti di lavorare con l'istanza dopo che è stata inviata.
In generale, qual è la differenza principale tra le implementazioni di Erlang e Akka?
In Erlang ogni attore ha il suo mucchio e il suo garbage collector. Quindi, nessuno stato mutabile condiviso, nessun gc stop-the-world. Questo ci dà qualità morbide in tempo reale. Ma paghi per copiare i dati da attore ad attore. In JVM (e .NET?) Heap e gc sono condivisi. Non hai un sovraccarico come in Erlang, ma dovresti essere disciplinato a non spararti ai tuoi stessi piedi.
Ora un paio di casi d'uso che io stesso ho incontrato.
Conoscete RabbitMQ: scambi, code, collegamenti ... Se la connessione fallisce, alcuni driver possono ridichiarli automaticamente tutti. Ho implementato questa logica con Akka, perché l'autista non si adattava alle mie esigenze. Era prima difficile capire quella logica, ma dopo che era riuscito a separare, cosa era effimero e cosa avrebbe dovuto persistere nel fallimento, le cose scattarono. Il primo è andato agli attori operai, mentre la lettera risiedeva in oggetti di scena dell'attore (che è in effetti una configurazione di istanza di attore) e supervisori. Questo è ciò che si intende quando si sente la resilienza dell'attore e l'auto-guarigione. Non è fuori dagli schemi, ma gli attori aiutano notevolmente a implementare questa logica il più semplice possibile, subito dopo averlo scoperto da solo.
Architettura esagonale e concorrenza. Ho implementato la specifica del protocollo CAS 3.0 per le esigenze interne utilizzando Akka.
Prima di tutto, core business, server http, client http, interazione db - tutti erano separati in diversi sottosistemi di attori e avevano una chiara superficie di interazione. Puoi testarli separatamente. Il core aziendale non sa, cos'è un protocollo http. Sapeva solo come gestire i comandi di business. Non sa nulla di db comprese le interfacce. Sa solo quali messaggi inviare e cosa ricevere. E db's ActorRef, ovviamente.
In secondo luogo, nel protocollo CAS ci sono alcune cose che devi controllare per una singola richiesta utente. Quindi, ho implementato ogni controllo in attori lavoratori separati. Sono configurati con ActorRef-s necessari e un timeout. O terminano l'elaborazione prima del timeout e si suicidano, o viene raggiunto il timeout e la risposta all'errore di produzione e, di nuovo, si suicidano. Nel frattempo, ci sono altri attori, che ho chiamato servizi. Fungono da supervisori per i lavoratori menzionati ed esistevano finché l'intero runtime. I loro ActorRef-s sono indirizzi statici, che è possibile utilizzare per configurare diversi componenti runtime durante l'avvio dell'applicazione.
Spero che questo aiuti