DarioSantarelli.Blog("UgiDotNet");

<sharing mode=”On” users=”*” />
posts - 176, comments - 105, trackbacks - 3

My Links

News


This is my personal blog. These postings are provided "AS IS" with no warranties, and confer no rights.




Tag Cloud

Archives

Post Categories

My English Blog

[WCF] Gestione delle istanze di un servizio e concorrenza

Indipendentemente dalla tecnologia utilizzata, un modo efficiente per aumentare le performance di un servizio è assicurare anzitutto un uso corretto delle risorse da allocare in memoria in fase di esecuzione. Sicuramente il primo passo ha a che vedere con l'analisi del comportamento delle istanze di un servizio in base allo scenario di interesse. Come molti sanno, in WCF la classe ServiceHost si preoccupa di gestire le istanze di un servizio, ma soprattuto di determinare quale di queste debba poi essere assegnata a ciascuna richiesta.
In questo contesto, viene definita l' Enumeration InstanceContextMode, da associare al behavior di un servizio WCF. Vediamo le opzioni possibili:

  • PerCall: viene creata una nuova istanza per ciascuna singola richiesta (anche se ci sono richieste multiple dallo stesso proxy client!!!). Questa modalità elimina alla radice il problema 'concorrenza' , in quanto ogni richiesta ha il suo scope e non mantiene alcuna informazione di stato. D'altra parte, in scenari in cui il ciclo di vita di un servizio è molto breve, questa modalità non fa altro che causare un elevato overhead computazionale.
  • PerSession (default): permette ad un' istanza di servizio di mantere lo stato nei confronti di più richieste provenienti dallo stesso client (il periodo di sessione scade di default ogni 10 min). Chiaramente, esiste la necessità di gestire richieste concorrenti che potrebbero generare situazioni di inconsistenza o deadlock.
  • Single: si utilizza una sola istanza del servizo per una qualunque richiesta, indipendentemente dal client di provenienza. Sicuramente questa è la modalità che elimina l'overhead di creazione/distruzione della classe, ma implica serie problematiche sia di accesso alle risorse che di security.

Inoltre è importante precisare che per istanze di servizio che supportano l'uso di sessioni, è possibile definire tramite la proprietà SessionMode di ServiceContract se l'uso stesso delle Session è permesso, obbligatorio o rifiutato. Tuttavia, se utilizziamo configurazioni PerSession, il client manterrà una relazione con l' istanza di servizio lato server indipendentemente dal tipo di ServiceContract (ed ovviamente qualora il binding/protocollo utilizzato lo permetta).

Concentriamoci ora sulla questione 'concorrenza' (ovvero sugli scenari PerSession e Single): se il codice all'interno di un servizio accede ad informazioni di stato o a risorse condivise, occorre prevedere meccanismi di accesso thread-safe onde evitare situazioni difficilmente riproducibili/debuggabili derivanti da richieste che tentano di accedere contemporaneamente alle stesse risorse.
A livello di ServiceBehavior quindi, possiamo impostare la proprietà ConcurrencyMode, che può assumere i seguenti tre valori:

  • Single (default): specifica la modalità "single threaded" più sicura in quanto previene la possibilità di deadlock. Infatti, il runtime WCF si preoccuperà di bloccare le richieste su un'istanza di servizio se essa è occupata. Le richieste in eccesso sono gestite quindi in una coda FIFO. Ovviamente, in scenari PerCall questa è l'unica opzione disponibile, mentre in scenari PerSession e Single questa soluzione abbassa il throughput.
  • Reentrant: opzione più performante ma meno sicura rispetto alla Single, poiché permette a thread diversi di gestire istanze diverse, ma in maniera tale per cui ci sia sempre e solo un thread attivo per volta.
  • Multiple: permette l'esecuzione di più thread contemporaneamente, rendendo seriamente possibili situazioni di deadlock. Se da una parte questa è l'opzione più performante (il numero di thread attivi/chiamate concorrenti può essere limitato da configurazione nella sezione serviceThrottling), dall'altra è la più pericolosa.

In conclusione, di default WCF ci predispone uno scenario PerSession con runtime single-threaded

[ServiceContract(SessionMode=SessionMode.Allowed)]
public interface IService { ... }


[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession,
                 ConcurrencyMode=ConcurrencyMode.Single)]

public class MyService : IService
{
  // Service Implementation...
}

 
Technorati tags:  WCF

Print | posted on domenica 9 marzo 2008 14:02 |

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET