WCF Throttling

فرض کنید که یک سرویس WCF دارید که می‌تواند به ۱۰۰ نفر به طور همزمان خدمات دهد. حال اگر این ۱۰۰ نفر به ۱۱۰ نفر افزایش پیدا کند چه اتفاقی می‌افتد؟ به احتمال زیاد سیستم از کار افتاده، کل ۱۱۰ نفر از خدمات محروم می‌شوند، نیاز به restart سرویس مربوطه پیدا می‌کنید و در نهایت باید به مدیریت سیستم هم در قبال از کار افتادن کلی سرویس جوابگو باشید.

حال مجدداً فرض کنید امکانی وجود دارد که با آن می‌توان سرویس را مجبور کرد که اگر آن ۱۰۰ نفر حد نهایی به ۱۱۰ نفر رسید، سرویس ۱۰۰ نفر اول قطع نشود ولی در عوض آن ۱۰ نفر جدید در صف دریافت سرویس قرار بگیرند. به این ترتیب فقط آن ۱۰ نفر آخر از تاخیر سیستم شاکی خواهند شد و ضمناً سرویس دچار مشکل نخواهد شد. اسم این امکان WCF Throttling است. WCF Throttling می‌تواند از طریق configها محدودیت‌هایی را در تعداد افراد همزمان و خیلی چیزهای دیگر ایجاد کند و اضافه بر آنها را به طور خودکار در «صف دریافت خدمات» قرار دهد.

منبع:
فصل ۴ کتاب Oreilly Programming WCF Services

‫WCF Durable services چیست؟

در ارتباط با بحث Instance management فرض کنید حالت یک instance را در همه حالات حفظ کنید. مثلاً اگر کلاینت قطع شد یا از یک proxy دیگر استفاده کرد، یا حتی اگر سرور خاموش شد. منظور از حفظ حالت، حفظ اطلاعات داخلی instance آبجکت سرویس مثل فیلدهای private آن است. به این حالت durable service گفته می‌شود.

کاربرد durable serviceها در اجرای اعمال طولانی است که طی آن ممکن است کلاینت یا سرور یا هر دو چندین بار قطع شوند ولی در این حال نمی‌خواهیم کلاینت‌ها مجبور شوند آن کار طولانی را از اول شروع کنند.

منابع:

WCF Instance Management

هر سرویسی در WCF توسط یک کلاس ارائه می‌شود. مثلاً فرض کنید که سرویسی برای محاسبه حقوق یک کارمند وجود دارد. پیاده‌سازی این سرویس می‌تواند به شکل متودی از یک کلاس فرضی به نام CalcClass باشد. وقتی که کلاینتی به سرویس WCF مورد نظر وصل شده و یکی از متودهای آن را فراخوانی نماید، WCF یک instance از کلاس CalcClass ایجاد کرده و متود مورد نظر کلاینت را از آن فراخوانی می‌نماید. این موضوع که روش ایجاد instance به ازای هر درخواست است یا به ازای هر کلاینت یا…، روش Instance Management نام دارد.

در WCF سه نوع روش instance گیری موجود است:

۱- به ازای هر درخواست: Per-Call
۲- به ازای هر کلاینت: Per-Session
۳- یکی به ازای کل Application (برنامه): Singleton

هر کدام از این روش‌ها مزایا و معایب خودشان را دارد. مثلاً روش Per-Call کمی Performance کمتری دارد ولی Scalable است. روش Per-Session حتی روی پروتکل Web Service هم کار می‌کند اما کمی overhead دارد. روش Singleton به شدت مشکل Performance دارد ولی برای Applicationهایی مثل کار با پورت سخت‌افزار یا کنترل موتور مکانیکی فقط یک منبع دارند مناسب‌تر است.

منبع:
فصل ۴ کتاب Oreilly Programming WCF Services

WCF Per-Session instance management

Per-Session یکی دیگر از انواع Instance Management در WCF است. در این روش به ازای هر کلاینت (پراکسی) یک instance از آبجکت سرویس ایجاد می‌شود. Per-Session به عنوان یک روش statefull معادل روش برنامه‌نویسی Client-Serverی کلاسیک است. که در آن را کلاینت به سرور وصل شده و شروع به ارسال درخواست‌هایش می‌کند بدون آن که سرور بخواهد به ازای هر یک از درخواست‌ها یک session جدید ایجاد کند.

از Per-Session نمی‌توان روی همه پروتکل‌ها (Bindingها) استفاده کرد. مثلاً استفاده از آن با BasicHttpBinding که همان وب سرویس معمولی است امکان پذیر نیست. دلیل آن هم ماهیت stateless بودن پروتکل HTTP است. در روش Per-Session هم سرور و هم کلاینت می‌توانند به SessionId دسترسی پیدا کرده و از آن استفاده نمایند.

[ServiceContract(SessionMode = SessionMode.Allowed)]
interface IMyContract
{…}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
class MyService : IMyContract
{…}

WCF Per-Call instance management

Per-Call اصلی‌ترین نوع instance management سه‌گانه در WCF است. در این روش با هر request کلاینت، یعنی با فراخوانی هر یک از متودهای سرویس، یک instance از object سرویس ایجاد شده و پس از اتمام درخواست آن instance از بین می‌رود. روش Per-Call نسبت به بقیه دارای مزایایی است از جمله مشغول نگه نداشتن منابع سرور و Scalable بودن application. به این معنی که می‌توان سرویس WCF را روی چند سرور host کرده و یک Load Balancer درخواست‌ها را بین آنها تقسیم کند تا Performance بهتری به دست بیاید.

برای حفظ state در روش Per-Call می‌توان از کلاینت فراخوانی کننده یک چیزی شبیه به ID دریافت کرده و state کلاینت مورد بحث در جایی در سرور ذخیره کرد. تنظیم یک سرویس برای Per-Call بودن به این شکل است:

[ServiceContract]
interface IMyContract
{
[OperationContract]
void MyMethod();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract,IDisposable
{
int m_Counter = 0;
MyService()
{
Trace.WriteLine(“MyService.MyService()”);
}
public void MyMethod()
{
m_Counter++;
Trace.WriteLine(“Counter = ” + m_Counter);
}
public void Dispose()
{
Trace.WriteLine(“MyService.Dispose()”);
}
}