{"id":32470,"date":"2021-03-10T05:00:00","date_gmt":"2021-03-10T04:00:00","guid":{"rendered":"https:\/\/blexin.com\/?p=32470"},"modified":"2021-05-21T20:01:59","modified_gmt":"2021-05-21T18:01:59","slug":"scalabilita-e-resilienza-con-gli-akka-actors","status":"publish","type":"post","link":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/","title":{"rendered":"Scalabilit\u00e0 e resilienza con gli Akka Actors"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"32472\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/attachment\/6_21_1105x656_blog-actormodel-a\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&amp;ssl=1\" data-orig-size=\"1105,656\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"6_21_1105x656_blog-actormodel-A\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-32472\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A-1024x608.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Un nostro cliente, operante nell\u2019ambito del gaming, ci ha commissionato una piattaforma per la gestione di un campionato di calcio virtuale, con classifiche sia di squadra che individuali.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dopo aver analizzato il problema, ci siamo chiesti come realizzare un sistema che tenesse aggiornate le classifiche e le statistiche a fronte dei risultati di singole partite (o magari, ad esempio, del gol o dell\u2019ammonizione di un calciatore), mantenendo il sistema scalabile e resiliente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Una delle soluzioni migliori che abbiamo trovato \u00e8 stata utilizzare gli Akka Actors, disponibili su ambiente .NET tramite il pacchetto Akka.NET (<a href=\"https:\/\/getakka.net\/articles\/intro\/what-is-akka.html\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/getakka.net\/articles\/intro\/what-is-akka.html<\/a>). Vengono utilizzati con particolare successo nei sistemi distribuiti e nelle architetture virtualizzate, in cui componenti possono talvolta bloccarsi senza dare alcuna risposta, i messaggi possono essere persi e c\u2019\u00e8 latenza di rete.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per far fronte a queste esigenze, Akka.NET ci offre:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Comportamento multi-thread&nbsp;anche&nbsp;senza l&#8217;utilizzo di costrutti di concorrenza di basso livello come&nbsp;atomics&nbsp;o lock;<\/li><li>Comunicazione remota trasparente tra i sistemi e i loro componenti;&nbsp;<\/li><li>Un&#8217;architettura clusterizzata, ad alta disponibilit\u00e0, elastica, scalabile.&nbsp;<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Inoltre, vengono messi a disposizione degli sviluppatori pacchetti come Akka.Cluster e Akka.Cluster.Sharding, che consentono la configurazione di cluster per distribuire gli attori su pi\u00f9 nodi.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Akka.NET si basa sul pattern Actor model (<a href=\"https:\/\/hal.archives-ouvertes.fr\/hal-01163534v7\/document\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/hal.archives-ouvertes.fr\/hal-01163534v7\/document<\/a>) e fornisce un insieme di librerie per implementare correttamente questo pattern, in modo da ottenere un livello pi\u00f9 alto di astrazione e rendere pi\u00f9 facile la progettazione di sistemi concorrenti, paralleli e distribuiti.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Actor Model&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La principale caratteristica degli attori \u00e8 quella di modellare il mondo come entit\u00e0&nbsp;stateful&nbsp;che comunicano tra loro scambiandosi messaggi, per cui, l\u2019Actor&nbsp;model&nbsp;fornisce un\u2019astrazione che consente&nbsp;di progettare&nbsp;un&#8217;applicazione in termini di comunicazione tra i componenti.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Come entit\u00e0 computazionali, gli attori hanno le seguenti caratteristiche:&nbsp;<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Comunicano tra loro con messaggi asincroni<\/li><li>Gestiscono il proprio stato&nbsp;<\/li><li>Quando rispondono a un messaggio, possono:&nbsp;<ul><li>Creare altri attori figli<\/li><li>Inviare messaggi ad altri attori&nbsp;<\/li><li>Fermare s\u00e9 stessi o gli attori figli&nbsp;<\/li><\/ul><\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Di conseguenza, nell\u2019Actor model due attori non potranno mai condividere la stessa memoria, n\u00e9 modificare direttamente lo stato di un altro attore. Dovr\u00e0 sempre mandare un messaggio all\u2019attore che vuole modificare e sar\u00e0 quindi il ricevente che si prender\u00e0 cura di recepire ed elaborare il messaggio.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"555\" data-attachment-id=\"32480\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/attachment\/actormodel\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ActorModel.png?fit=1480%2C802&amp;ssl=1\" data-orig-size=\"1480,802\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ActorModel\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ActorModel.png?fit=1024%2C555&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ActorModel.png?resize=1024%2C555&#038;ssl=1\" alt=\"Actor Model\" class=\"wp-image-32480\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/ActorModel-980x531.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/ActorModel-480x260.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Architettura applicazione&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Andiamo quindi a introdurre la nostra soluzione, con un occhio anche all\u2019architettura degli Akka Actors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Essa sar\u00e0 composta da un applicazione front-end scritta in Angular, uno strato di Web API .NET Core actor based con supporto al long polling tramite l\u2019utilizzo di un hub SignalR e, infine, un simulatore di eventi.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"364\" data-attachment-id=\"32482\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/attachment\/applicationdiagram\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ApplicationDiagram.png?fit=595%2C364&amp;ssl=1\" data-orig-size=\"595,364\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ApplicationDiagram\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ApplicationDiagram.png?fit=595%2C364&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/ApplicationDiagram.png?resize=595%2C364&#038;ssl=1\" alt=\"Application diagram\" class=\"wp-image-32482\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/ApplicationDiagram.png 595w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/ApplicationDiagram-480x294.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 595px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Quando si crea un attore in Akka.NET, questo ha sicuramente un genitore, poich\u00e9 gli attori sono organizzati in una struttura ad albero, e ogni attore viene creato all\u2019interno di un altro. In maniera gerarchica, l\u2019attore creato diventa figlio dell\u2019attore genitore da cui \u00e8 stato creato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al vertice dell\u2019albero, c\u2019\u00e8 un livello predefinito costituito da 3 attori:<strong> root guardian<\/strong> (\/), genitore di tutti gli attori del sistema, che ha come figli <strong>user guardian<\/strong> (\/user), che \u00e8 genitore di tutti gli attori creati dall\u2019utente, e il <strong>system guardian<\/strong> (\/system), usato per supervisionare e assicurare la chiusura ordinata degli attori, preservando il logging degli eventi. I nomi degli attori di sistema contengono la parola <em>guardian<\/em> poich\u00e9 essi fungono da supervisori per tutti i figli creati sotto di essi.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"658\" height=\"373\" data-attachment-id=\"32486\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/attachment\/akka-three\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Akka-Three.png?fit=658%2C373&amp;ssl=1\" data-orig-size=\"658,373\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Akka-Three\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Akka-Three.png?fit=658%2C373&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Akka-Three.png?resize=658%2C373&#038;ssl=1\" alt=\"Akka tree\" class=\"wp-image-32486\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/Akka-Three.png 658w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/Akka-Three-480x272.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 658px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Nel nostro progetto abbiamo introdotto tre tipi di attori: due di primo livello, ovvero MatchesActor, che servir\u00e0 per aggiornare i dati relativi a tutte le partite, e StandingsActor, per i dati della classifica, e uno di secondo livello, MatchActor, che servir\u00e0 a gestire i dati della singola partita.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nvar firstRef = System.ActorOf(Props.Create(() =&gt; new MatchesActor()), &quot;matches&quot;); \n\nConsole.WriteLine($&quot;First: {firstRef}&quot;); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Che&nbsp;restituir\u00e0&nbsp;in output:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nFirst: Actor&#x5B;akka:\/\/akkaActors\/user\/matches#1213311313] \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Nel nostro progetto, la&nbsp;configurazione&nbsp;degli attori di primo livello \u00e8 stata realizzata nella classe&nbsp;ActorsEnvironment, in particolar modo nel metodo&nbsp;Configure, cos\u00ec realizzato:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static ActorsEnvironment Configure(IServiceProvider provider) \n\n{ \n\n        var hubContext = provider.GetService&lt;IHubContext&lt;Hub&gt;&gt;(); \n\n        var system = ActorSystem.Create(&quot;akkaActors&quot;); \n \n        system.ActorOf(Props.Create(() =&gt; new MatchesActor()), &quot;matches&quot;); \n        system.ActorOf(Props.Create(() =&gt; new StandingsActor()), &quot;standings&quot;); \n\n        return new ActorsEnvironment(system); \n\n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Tale metodo viene richiamato nello Startup.cs, in ConfigureServices:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n services.AddSingleton&lt;ActorsEnvironment&gt;(context =&gt; ActorsEnvironment.CreateAndConfigure(context));\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Quindi, nel nostro caso, l\u2019attore di primo livello di tipo MatchesActor, avr\u00e0 il path \/user\/matches.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Abbiamo inoltre definito delle costanti per i path dei nostri Actors:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class ActorPaths \n\n{ \n        public const string MatchesActor = &quot;\/user\/matches&quot;; \n        public const string StandingsActor = &quot;\/user\/standings&quot;; \n        public const string SignalRActor = &quot;\/user\/signalR&quot;; \n\n        public const string AllActors = &quot;\/user\/*\/*&quot;; \n } \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Per creare attori di livello non superiore, invece, bisogna invocare Context.ActorOf() dall\u2019interno dell\u2019attore padre, come da codice seguente:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class MatchActor : UntypedActor \n{ \n} \n\npublic class MatchesActor : UntypedActor \n{ \n\n        protected override void OnReceive(object message) \n        { \n                switch (message) \n                { \n                        case &quot;create-new&quot;: \n                        IActorRef secondRef = Context.ActorOf(Props.Create(() =&gt; new MatchActor()), $&quot;first-match&quot;); \n                        Console.WriteLine($&quot;Second: {secondRef}&quot;); \n                        break; \n                } \n        } \n} \n\nvar firstRef = Sys.ActorOf(Props.Create&lt;MatchesActor&gt;(), &quot;matches&quot;); \nConsole.WriteLine($&quot;First: {firstRef}&quot;); \nfirstRef.Tell(&quot;create-new&quot;, ActorRefs.NoSender); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In questo modo creiamo un attore di primo livello, ne stampiamo il riferimento, e gli inviamo un messaggio contenente l\u2019id del figlio eventualmente da creare e di cui viene stampato il riferimento.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019output generato \u00e8:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nFirst : Actor&#x5B;akka:\/\/akkaActors\/user\/matches#1213311313] \nSecond: Actor&#x5B;akka:\/\/akkaActors\/user\/matches\/first-match#12261716] \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ciclo di vita&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Un attore pu\u00f2 essere stoppato tramite l\u2019invocazione del metodo Context.Stop(actorRef), ma, come best practice, \u00e8 preferibile inviare un messaggio all\u2019attore che si intende stoppare e lasciare che sia lui a fermare s\u00e9 stesso, tramite l\u2019invocazione di Context.Stop(self).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quando un attore viene stoppato, lo stesso avviene ricorsivamente per tutti i suoi figli, in modo da evitare perdita di risorse e semplificare la pulizia della memoria.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le API degli actors permettono l\u2019override dei metodi PreStart(), invocato dopo che l\u2019attore \u00e8 stato creato ma prima che legga il suo primo messaggio, e PostStop(), invocato dopo che l\u2019attore \u00e8 stato fermato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nel nostro caso:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class MatchActor : ReceiveActor \n{ \n        protected override void PreStart() \n        { \n                Console.WriteLine($&quot;Match actor {Self.Path.Name} started&quot;); \n        } \n\n        protected override void PostStop() \n        { \n                Console.WriteLine($&quot;Match actor {Self.Path.Name} stopped&quot;); \n        } \n\n} \n\npublic class MatchesActor : ReceiveActor \n{ \n        protected override void PreStart() \n        { \n                Console.WriteLine($&quot;Matches actor {Self.Path.Name} started&quot;); \n        } \n\n        protected override void PostStop() \n        { \n                Console.WriteLine($&quot;Matches actor {Self.Path.Name} stopped&quot;); \n        } \n\n        protected override void OnReceive(object message) \n        { \n                switch (message) \n                { \n                        case &quot;create-new&quot;: \n                                IActorRef secondRef = Context.ActorOf(Props.Create(() =&gt; new MatchActor()), $&quot;first-match&quot;); \n                        \n                                break;             \n                        case &quot;stop&quot;: \n                                Context.Stop(Self); \n                                break;             \n                }   \n\n        }\n \n} \n\nvar firstRef = Sys.ActorOf(Props.Create&lt;MatchesActor&gt;(), &quot;matches&quot;); \nfirstRef.Tell(&quot;create-new&quot;, ActorRefs.NoSender); \nfirstRef.Tell(&quot;stop&quot;); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">L\u2019output&nbsp;generato&nbsp;\u00e8:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nMatches actor matches started \nMatch actor first-match started \nMatch actor first-match stopped \nMatches actor matches stopped \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Da ci\u00f2 si evince che l\u2019invocazione del PostStop() per gli attori figli avviene prima di quella del padre.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Gestione degli errori&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Quando un attore va in errore, viene temporaneamente sospeso e l\u2019informazione dell\u2019errore viene propagata al genitore che deve decidere come gestirlo.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se non viene modificata la gestione degli errori, la strategia di default prevede di stoppare e far ripartire l\u2019attore figlio, come si evince dall\u2019esempio di seguito.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class MatchActor : ReceiveActor \n{ \n        protected override void PreStart() \n        { \n                Console.WriteLine($&quot;Match actor {Self.Path.Name} started&quot;); \n        } \n\n        protected override void PostStop() \n        { \n                Console.WriteLine($&quot;Match actor {Self.Path.Name} stopped&quot;); \n        } \n\n        protected override void OnReceive(object message) \n        { \n                switch (message) \n                { \n                        case &quot;fail&quot;: \n                                Console.WriteLine(&quot;Match actor fails&quot;); \n                                throw new Exception(&quot;I failed!&quot;); \n                } \n        } \n} \n\npublic class MatchesActor : ReceiveActor \n { \n        protected override void PreStart() \n        { \n                Console.WriteLine($&quot;Matches actor {Self.Path.Name} started&quot;); \n        } \n\n        protected override void PostStop() \n        { \n                Console.WriteLine($&quot;Matches actor {Self.Path.Name} stopped&quot;); \n        } \n\n\nprotected override void OnReceive(object message) \n        { \n                switch (message) \n                { \n                        case &quot;fail-child&quot;: \n                                IActorRef child = Context.ActorOf(Props.Create(() =&gt; new MatchActor()), $&quot;first-match&quot;); \n\n                                child.Tell(&quot;fail&quot;); \n                                break;             \n                } \n\n        } \n\n  } \n\nvar firstRef = Sys.ActorOf(Props.Create&lt;MatchesActor&gt;(), &quot;matches&quot;); \nfirstRef.Tell(&quot;fail-child&quot;, ActorRefs.NoSender); \nfirstRef.Tell(&quot;stop&quot;); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">L\u2019output&nbsp;generato&nbsp;\u00e8:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nMatches actor matches started \nMatch actor first-match started \nMatch actor fails \nMatches actor matches stopped \nMatches actor matches started \n\n&#x5B;ERROR]&#x5B;11.02.2021 13:34:50]&#x5B;Thread 0003]&#x5B;akka:\/\/akkaActors\/user\/matches\/first-match] I failed! \nCause: System.Exception: I failed! \n   at AkkaActors.MatchActor.OnReceive(Object message) \n   at Akka.Actor.UntypedActor.Receive(Object message) \n   at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message) \n   at Akka.Actor.ActorCell.ReceiveMessage(Object message) \n   at Akka.Actor.ActorCell.Invoke(Envelope envelope) \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Nell\u2019output notiamo che l\u2019attore padre viene fermato e riparte immediatamente, e vengono richiamati in successione PostStop() e PreStart().<br>Per avere un comportamento diverso dalla prima esecuzione a quelle successive, possiamo fare l\u2019override dei metodi PreRestart() e PostRestart().<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Per quanto riguarda gli eventi gestiti, abbiamo 3 tipi per l\u2019actor MatchesActor:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>MatchStarted,<\/li><li>MatchEnded&nbsp;<\/li><li>MatchScoreChanged.&nbsp;<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Questi metodi sono cos\u00ec definiti nel codice:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class MatchStarted \n{ \n        public int MatchId { get; set; } \n} \n\n public class MatchEnded \n{ \n        public int MatchId { get; set; } \n} \n\n public class MatchScoreChanged \n{ \n        public int MatchId { get; set; } \n        public int Team1Score { get; set; } \n        public int Team2Score { get; set; } \n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Essi vengono gestiti registrando degli&nbsp;handler&nbsp;in&nbsp;MatchesActor, in questo modo:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic MatchesActor() \n{ \n        ReceiveAsync&lt;MatchStarted&gt;(request =&gt; Handle(request)); \n        ReceiveAsync&lt;MatchEnded&gt;(request =&gt; Handle(request)); \n        ReceiveAsync&lt;MatchScoreChanged&gt;(request =&gt; Handle(request)); \n} \n\nprivate IActorRef GetMatchActor(int matchId) \n{ \n        var childActor = Context.Child($&quot;{matchId}&quot;); \n\n        if (childActor is Nobody) \n        { \n                childActor = Context.ActorOf(Props.Create(() =&gt; new MatchActor()), $&quot;{matchId}&quot;); \n        } \n\n         return childActor; \n\n} \n\n private async Task Handle(MatchStarted request) \n{ \n        var child = GetMatchActor(request.MatchId); \n        child.Forward(request); \n} \n \/\/ &#x5B;...] \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In questo modo, i messaggi vengono inoltrati al&nbsp;MatchActor&nbsp;di riferimento, che li gestisce:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic MatchActor() \n{ \n        ReceiveAsync&lt;MatchStarted&gt;(request =&gt; Handle(request)); \n        ReceiveAsync&lt;MatchEnded&gt;(request =&gt; Handle(request)); \n        ReceiveAsync&lt;MatchScoreChanged&gt;(request =&gt; Handle(request)); \n} \n\n private async Task Handle(MatchStarted request) \n{ \n        CurrentMatch.Started = true; \n        CurrentMatch.Team1Score = 0; \n        CurrentMatch.Team2Score = 0; \n\n         Context.ActorSelection(ActorPaths.StandingsActor).Tell(new StandingsChanged() {  \n                Teams = new Dictionary&lt;string, int&gt;() \n                { \n                        { CurrentMatch.Team1, 1 }, \n                        { CurrentMatch.Team2, 1 } \n                } \n\n        }); \n        Context.ActorSelection(ActorPaths.SignalRActor).Tell(request); \n\n} \n \/\/ &#x5B;...] \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Dove&nbsp;StandingsChanged&nbsp;\u00e8 definito cos\u00ec:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class StandingsChanged \n{ \n        public Dictionary&lt;string, int&gt; Teams { get; set; } \n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">MatchActor gestisce la logica di aggiornamento della classifica e inoltra il messaggio prima allo StandingsActor che aggiorna la classifica ed \u00e8 cos\u00ec definito:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class StandingsActor : ReceiveActor \n{ \n        private Standings CurrentStandings { get; set; } \n        public StandingsActor() \n\n        { \n                Receive&lt;StandingsChanged&gt;(request =&gt; Handle(request)); \n        } \n  \n        private void Handle(StandingsChanged request) \n        { \n                CurrentStandings = new Standings() \n                { \n                        Teams = request.Teams \n                }; \n\n                Context.ActorSelection(ActorPaths.SignalRActor).Tell(request); \n\n        } \n\n }  \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Successivamente, se c\u2019\u00e8 necessit\u00e0 che gli gli eventi vengano aggiornati nella UI, possono essere inoltrati al SignalRActor, che si occuper\u00e0 di fare il polling in broadcast dei dati da mostrare nella UI in base alla tipologia di messaggio da gestire:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class SignalRActor : ReceiveActor \n{ \n        private readonly IHubContext&lt;Hub&gt; hubContext; \n\n        public SignalRActor(IHubContext&lt;Hub&gt; hubContext) \n        { \n                this.hubContext = hubContext; \n\n                Receive&lt;MatchStarted&gt;(message =&gt; Handle(message)); \n                Receive&lt;MatchEnded&gt;(message =&gt; Handle(message)); \n                Receive&lt;MatchScoreChanged&gt;(message =&gt; Handle(message)); \n                Receive&lt;StandingsChanged&gt;(message =&gt; Handle(message)); \n\n        } \n\n         private void Handle(MatchStarted message) \n        { \n                hubContext.Clients.All.SendAsync(&quot;BroadcastMatchStarted&quot;, message); \n        } \n  \n        private void Handle(MatchEnded message) \n        { \n                hubContext.Clients.All.SendAsync(&quot;BroadcastMatchEnded&quot;, message); \n        } \n\n        private void Handle(MatchScoreChanged message) \n        { \n                hubContext.Clients.All.SendAsync(&quot;BroadcastMatchScoreChanged&quot;, message); \n        } \n  \n        private void Handle(StandingsChanged message) \n        { \n                 hubContext.Clients.All.SendAsync(&quot;BroadcastStandingsChanged&quot;, message); \n        } \n\n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">I nostri Web API controllers utilizzano gli attori ed effettuano delle operazioni tramite essi.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ad esempio, il MatchesController contiene i 3 endpoint per la modifica dello stato dei match:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n &#x5B;HttpPut] \n&#x5B;Route(&quot;{matchId}\/start&quot;)] \npublic IActionResult StartMatch(int matchId) \n{ \n        environment \n                .SelectActor(ActorPaths.MatchesActor) \n                .Tell(new MatchStarted \n                { \n                        MatchId = matchId \n                }); \n\n         return Ok(); \n\n} \n\n&#x5B;HttpPut] \n&#x5B;Route(&quot;{matchId}\/stop&quot;)] \npublic IActionResult StopMatch(int matchId) \n{ \n        environment \n                .SelectActor(ActorPaths.MatchesActor) \n                .Tell(new MatchEnded \n                { \n                        MatchId = matchId \n                }); \n\n        return Ok(); \n\n} \n \n&#x5B;HttpPut] \n&#x5B;Route(&quot;{matchId}\/changescore\/{team1Score}\/{team2Score}&quot;)] \npublic IActionResult ChangeScore(int matchId, int team1Score, int team2Score) \n{ \n        environment \n                .SelectActor(ActorPaths.MatchesActor) \n                .Tell(new MatchScoreChanged \n                { \n                        MatchId = matchId, \n                        Team1Score = team1Score, \n                        Team2Score = team2Score \n                }); \n  \n        return Ok(); \n\n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Lato applicazione&nbsp;front-end, \u00e8 importante segnalare l\u2019implementazione di un&nbsp;SignalRService, che&nbsp;serve a&nbsp;intercettare le comunicazioni con l\u2019hub di&nbsp;SignalR:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nexport class SignalRService { \n        private hub: HubConnection; \n        \n        constructor() { \n                this.hub = new signalR.HubConnectionBuilder() \n                       \t.withUrl(`${environment.websocketUrl}akkaActorsHub`) \n        \t\t.build(); \n\n                this.hub.start().then(() =&gt; { \n               \t        console.log(`Hub connection started`); \n    \t\t        }).catch(err =&gt; document.write(err)); \n\n        } \n\n         public on&lt;T&gt;(name: string): Observable&lt;T&gt; { \n                const subject = new Subject&lt;T&gt;(); \n\n                this.hub.on(name, (data) =&gt; { \n                subject.next(data); \n                }); \n\n                return subject.asObservable(); \n\n        } \n\n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Questa classe viene poi iniettata nei component Angular in cui \u00e8 necessaria, pi\u00f9 precisamente nel metodo ngOnInit, in questo modo:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nngOnInit() { \n        const onMatchScoreChanged$: Observable&lt;any&gt; = this.signalR.on(`BroadcastMatchScoreChanged`); \n        onMatchScoreChanged$.subscribe((message: any) =&gt; { \n                \/\/Do something \n        }); \n        } \n}); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Per i nostri test abbiamo creato un simulatore di eventi che provvede a far iniziare due match e cambia i risultati, prima di fermarli definitivamente.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gli eventi vengono inviati tramite protocollo REST alle Web API:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate static void Send(string endpoint, StringContent content) \n{ \n        _client.PostAsync(endpoint, content).Wait(); \n} \n\n static void Main(string&#x5B;] args) \n{ \n        _client = new HttpClient { BaseAddress = new Uri(&quot;http:\/\/localhost:5000&quot;) }; \n\n        _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&quot;application\/json&quot;)); \n\n        Send(&quot;api\/matches\/1\/start&quot;, &quot;&quot;); \n        Send(&quot;api\/matches\/2\/start&quot;, &quot;&quot;); \n\n        var content = new StringContent(JsonConvert.SerializeObject(new \n        { \n                Team1Score = 1, \n                Team2Score = 0 \n        }), Encoding.UTF8, &quot;application\/json&quot;); \n\n        Send(&quot;api\/matches\/2\/updatescore&quot;, content); \n\n        \/\/ other events\u2026 \n\n        Send(&quot;api\/matches\/2\/stop&quot;, &quot;&quot;); \n        Send(&quot;api\/matches\/1\/stop&quot;, &quot;&quot;); \n\n}\t \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Esecuzione progetto&nbsp;<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Avviando la nostra soluzione di test, possiamo vedere una dashboard con dei dati che si aggiornano ogni qual volta arriva un evento dal simulatore:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"975\" height=\"384\" data-attachment-id=\"32505\" data-permalink=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/attachment\/application-running\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Application-Running.png?fit=975%2C384&amp;ssl=1\" data-orig-size=\"975,384\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Application-Running\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Application-Running.png?fit=975%2C384&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/Application-Running.png?resize=975%2C384&#038;ssl=1\" alt=\"application running\" class=\"wp-image-32505\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/Application-Running.png 975w, https:\/\/blexin.com\/wp-content\/uploads\/2021\/03\/Application-Running-480x189.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 975px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Mi auguro di aver suscitato la vostra curiosit\u00e0 sull\u2019argomento.&nbsp;Sul nostro blog, troverai altri articoli sull&#8217;architettura software.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Il codice sorgente utilizzato in questo articolo \u00e8 <a href=\"https:\/\/github.com\/enricobencivenga\/AkkaActors\" target=\"_blank\" rel=\"noreferrer noopener\">disponibile&nbsp;qui<\/a>.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al prossimo articolo.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Vediamo come implementare Actor Model in .NET<\/p>\n","protected":false},"author":196716247,"featured_media":32472,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637374],"tags":[688637420,688637541,688637382,688637536],"class_list":["post-32470","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-net","tag-dotnetcore","tag-c","tag-swdesign"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin<\/title>\n<meta name=\"description\" content=\"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin\" \/>\n<meta property=\"og:description\" content=\"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2021-03-10T04:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-21T18:01:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1105\" \/>\n\t<meta property=\"og:image:height\" content=\"656\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Enrico Bencivenga\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Enrico Bencivenga\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/\"},\"author\":{\"name\":\"Enrico Bencivenga\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\"},\"headline\":\"Scalabilit\u00e0 e resilienza con gli Akka Actors\",\"datePublished\":\"2021-03-10T04:00:00+00:00\",\"dateModified\":\"2021-05-21T18:01:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/\"},\"wordCount\":1307,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1\",\"keywords\":[\".Net\",\".NetCore\",\"C#\",\"softwaredesign\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/\",\"name\":\"Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1\",\"datePublished\":\"2021-03-10T04:00:00+00:00\",\"dateModified\":\"2021-05-21T18:01:59+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\"},\"description\":\"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2021\\\/03\\\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1\",\"width\":1105,\"height\":656},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/blog\\\/scalabilita-e-resilienza-con-gli-akka-actors\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Scalabilit\u00e0 e resilienza con gli Akka Actors\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/it\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\",\"name\":\"Enrico Bencivenga\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"caption\":\"Enrico Bencivenga\"},\"url\":\"https:\\\/\\\/blexin.com\\\/it\\\/author\\\/enrico-bencivengablexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin","description":"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/","og_locale":"it_IT","og_type":"article","og_title":"Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin","og_description":"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.","og_url":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/","og_site_name":"Blexin","article_published_time":"2021-03-10T04:00:00+00:00","article_modified_time":"2021-05-21T18:01:59+00:00","og_image":[{"width":1105,"height":656,"url":"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","type":"image\/png"}],"author":"Enrico Bencivenga","twitter_card":"summary_large_image","twitter_misc":{"Scritto da":"Enrico Bencivenga","Tempo di lettura stimato":"10 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/"},"author":{"name":"Enrico Bencivenga","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194"},"headline":"Scalabilit\u00e0 e resilienza con gli Akka Actors","datePublished":"2021-03-10T04:00:00+00:00","dateModified":"2021-05-21T18:01:59+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/"},"wordCount":1307,"image":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","keywords":[".Net",".NetCore","C#","softwaredesign"],"articleSection":["Blog"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/","url":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/","name":"Scalabilit\u00e0 e resilienza con gli Akka Actors - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","datePublished":"2021-03-10T04:00:00+00:00","dateModified":"2021-05-21T18:01:59+00:00","author":{"@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194"},"description":"Con gli Akka Actor puoi modellare le tue applicazioni .NET per consentire la comunicazione asincrona tra i componenti.","breadcrumb":{"@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","width":1105,"height":656},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/it\/blog\/scalabilita-e-resilienza-con-gli-akka-actors\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/it\/"},{"@type":"ListItem","position":2,"name":"Scalabilit\u00e0 e resilienza con gli Akka Actors"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/it\/#website","url":"https:\/\/blexin.com\/it\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Person","@id":"https:\/\/blexin.com\/it\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194","name":"Enrico Bencivenga","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","caption":"Enrico Bencivenga"},"url":"https:\/\/blexin.com\/it\/author\/enrico-bencivengablexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2021\/03\/6_21_1105x656_blog-actormodel-A.png?fit=1105%2C656&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-8rI","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/32470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/users\/196716247"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/comments?post=32470"}],"version-history":[{"count":36,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/32470\/revisions"}],"predecessor-version":[{"id":32544,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/posts\/32470\/revisions\/32544"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media\/32472"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/media?parent=32470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/categories?post=32470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/it\/wp-json\/wp\/v2\/tags?post=32470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}