2014-12-24 13 views
13

Ho creato un servizio con un'API RESTful in ASP.NET, ospitato in IIS. All'interno di questo servizio, mi piacerebbe creare un sistema di attori con Akka.NET.Sistema di attori Akka.NET in ASP.NET

Dopo aver creato il sistema di attore:

var actorSystem = ActorSystem.Create("myActorSystem"); 

la seguente eccezione viene lanciata:

Una prima eccezione di possibilità di tipo 'System.InvalidOperationException' in System.Web.dll Ulteriori informazioni : Non è possibile avviare un'operazione asincrona in questo momento. Le operazioni asincrone possono essere avviate solo all'interno di un gestore o modulo asincrono o durante determinati eventi nel ciclo di vita della pagina. Se si è verificata questa eccezione durante l'esecuzione di una pagina, assicurarsi che la pagina sia contrassegnata con <% @ Page Async = "true"%>. Questa eccezione può anche indicare un tentativo di chiamare un metodo "async void", che generalmente non è supportato nell'elaborazione della richiesta ASP.NET. Invece, il metodo asincrono dovrebbe restituire un'attività e il chiamante dovrebbe attendere.

Il sistema attore è intrinsecamente un sistema concorrente con lo scambio di messaggi asincroni tra attori. Come spiegato here, questo sistema di attori non sarebbe sopravvissuto a IIS eliminando AppDomain, il che probabilmente è il motivo per cui viene generata l'eccezione di cui sopra.

This article spiega come eseguire attività in background in ASP.NET. Tuttavia, non vedo come potrei usarlo per il mio sistema di attori, poiché non ho alcun controllo sul ciclo di vita delle attività in background che potrebbero essere create da Akka.NET.

C'è un modo per farlo funzionare, o dovrei abbandonare l'idea di avere un sistema di attori in un'applicazione ASP.NET?

EDIT: Ho anche visto una domanda su Stackoverflow su implementing a REST service using Akka. Qualunque consiglio su una soluzione simile a Spray toolkit, ma funzionante per Akka.NET sarebbe il benvenuto.

+1

Il modello di attore sembra fantastico. Ma ne hai davvero bisogno? – odinserj

+1

Sto provando questo come una dimostrazione del concetto, non ne ho assolutamente bisogno. Una conclusione potrebbe essere che sarebbe troppo complicato. – Odsh

risposta

22

Mantieni ActorSystem come proprietà condivisa in alcuni contenitori di classi statiche, in questo modo è possibile accedervi dal resto dell'applicazione. Sistema Attore inizializzazione/smaltimento può essere fatto da:

  • Global.asax - utilizzare ActorSystem.Create(...) all'interno Global.asax Application_Start e smaltire con system.Shutdown() su Application_End.
  • OWIN - creare sistema di attore nel metodo di OWIN Startup.Configuration e spegnerlo legandosi a host.OnAppDisposing evento (how-to link).

Ricordare che IIS avvierà l'app Web solo dopo la prima richiesta e la interromperà automaticamente dopo un po 'di tempo in cui è inattiva. Pertanto assicurati che lo script di distribuzione esegua il ping dell'applicazione dopo la pubblicazione e imposti il ​​timeout di inattività (link) per un tempo sufficientemente lungo se desideri che il tuo sistema di attori Akka venga eseguito continuamente.

Seconda opzione

separata logica vostro attore del sistema e distribuirlo, per esempio, come servizio di Windows (o demone Linux). Attiva Akka.Riprova per esso e crea un client proxy, che inoltrerà tutte le attività sensibili a lunga esecuzione dell'applicazione al servizio esterno. Una soluzione simile viene spesso utilizzata per cose come programmatori o bus di eventi, quando la logica dell'applicazione deve funzionare continuamente.

+0

Grazie per la tua risposta Horusiath. Penso che dovrò andare con la seconda opzione. Il primo è difficile da applicare nel mio caso, dal momento che il sistema degli attori può potenzialmente eseguire attività molto lunghe o continue. – Odsh

25

Ho usato Akka.NET e Akka.Remote all'interno di applicazioni ASP.NET MVC che stanno eseguendo fino a 1000 richieste al secondo su EC2 - quindi condividerò alcuni dei suggerimenti e dei trucchi che ho usato per ottenerlo e funzionante con successo. Aveva una versione prototipo che usava anche Akka.Cluster ma finì per non aver spedito quella versione.

  • Il posto migliore per chiamare ActorSystem.Create è all'interno di Global.asax Application_Start().
  • Appendere a un riferimento statico all'oggetto ActorSystem all'interno di Global.asax stesso, utilizzando un campo o una proprietà statici. Aiuta a garantire che lo stesso ActorSystem non venga raccolto automaticamente in applicazioni di lunga durata.
  • Creare una classe helper statica separata per inizializzare qualsiasi attore di livello superiore di cui hanno bisogno le applicazioni, ovvero gli attori nella parte superiore della gerarchia /user/. Questa classe deve inoltre fornire percorsi degli attori che i controller ASP.MVC e i metodi di azione possono utilizzare per le operazioni Tell e Ask.

La creazione di ActorSystem è un'operazione costosa, poiché molti elementi a livello di sistema vengono attivati ​​contemporaneamente. È sicuramente meglio farlo una volta all'avvio dell'applicazione e quindi memorizzare solo i risultati nella classe Application.

La creazione di singole istanze di attori è economica: si dovrebbe essere in grado di fare questo senza problemi nei metodi di azione ASP.NET MVC. Se visualizzi nuovamente questo errore, comunicaci quale parte del processo di gestione delle richieste si è verificato questo errore e con quale versione di ASP.NET.

+0

Grazie per la tua risposta Aaron. Come spiegato su [questo sito] (http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/), ASP .NET potrebbe abbattere il tuo AppDomain in qualsiasi momento, quindi interrompere qualsiasi esecuzione in background nella tua applicazione. Cosa succederebbe al tuo sistema di attori quando succederà? – Odsh

+0

In tutti questi scenari, Akka.NET è in esecuzione all'interno dell'AppDomain di ASP.NET - quindi, nel caso di uno qualsiasi degli scenari di Haack, l'app Web viene riciclata insieme al sistema degli attori (modifica di web.config, riciclo dei processi IIS). , ecc.) A seconda del tuo ambiente di hosting, puoi controllarli tutti attraverso le impostazioni di IIS e machine.config. Indipendentemente da ciò, ActorSystem sarà comunque attivo contemporaneamente alla tua applicazione web - non c'è nulla che passerà attraverso e ucciderà il tuo ActorSystem ma lascerai intatta l'app ASP.NET seguendo ciò che ho eluso sopra. – Aaronontheweb

+0

il sistema attore sarà attivo contemporaneamente alla mia applicazione web, sì. Quello che vorrei evitare è che questo sistema di attori viene fermato senza preavviso al momento del riciclo, con attori ancora attivi e code di messaggi non vuoti. – Odsh