Wednesday, January 18, 2012

CSLA Message Size Is HUGH ???

The project I am working on experiencing some performance issue, slow communication between server and client, system out of memory exception.

The project is a Silverlight Rich Internet Application.  Silverlight + Prism on the client, CSLA an application framework for middle tier, SQL Server at backend.  The hardware specification of the hosting environment is good enough for our current few pilot users, less than a hundred of users.

Since, hardware is good enough to support our current user load.  We decided to benchmark our middle tier CSLA, which we cannot get any existing benchmark from anywhere.  Nobody is using CSLA? :) We compared with WCF Service and WCF RIA Service as well.

The benchmark result is a little surprising and explain some of the issue we have.

Display a list object which contains 20 item objects, each item object has 11 properties, int, bool, datetime or string values.

Without IIS compression enabled.




With IIS compression enabled.





































IIS compression is one way only, for downloading data from server to client.  Sending data from client to server is NOT compressed.  It is getting worse when sending data from client to server using CSLA.  We use a single object which has 23 properties, int, bool, datetime and string values.


















Given a typical business unit who have 10 users and share a regular DSL line for internet connection which has a average of 100KB upstream speed,
10 x 6KB = 60KB / 100KB = 60%.
So, CSLA itself will use at least 60% of the bandwidth!!!

The big message size of CSLA is not only affecting the communication but also the memory usage on the Silverlight Client.  Why?






































Even if the message is IIS compressed in a smaller size for faster downloading, it will be uncompressed on the client, and Silverlight .NET runtime have to allocate enough memory to handle the uncompressed message which is much bigger than WCF Service or WCF RIA Service message.  This will cause extra CPU and memory usage, plus Silverlight .NET runtime is not as effecient as desktop .NET runtime, which will end with System.OutOfMemory issue sometime.

Are you also using CSLA or planning to use CSLA for your Silverlight Rich Internet Application?  Let me know your performance experience.

Deep Zoom Service Is NOT Free

The project I am working on is using Deep Zoom Service to display images uploaded by the user.  Based on the network traffic monitored by Fiddler and Silverlight client memory debugging by WinDbg, we found out Deep Zoom Service is free for development, but in order to support it, the deployment environment must have extra internet bandwidth, and Silvelight client must have enough free memory.  See below test results using a 1MB size of jpeg file, after image displayed in System.Windows.Controls.MultiScaleImage control, doing only a few zoom in, zoom out and move directions.

Network traffic monitored by Fidder, total 43 network round trip for just displaying one image.




































Memory usage debugging by WinDbg, total 12MB is used for one image.

0:048> !dumpheap -mt 7ac18ea8
 Address       MT     Size
287509e8 7ac18ea8       72    

total 0 objects
Statistics:

      MT    Count    TotalSize Class Name
7ac18ea8        1           72 System.Windows.Controls.MultiScaleImage
Total 1 objects

0:048> !objsize 287509e8
sizeof(287509e8) =     12690624 (    0xc1a4c0) bytes (System.Windows.Controls.MultiScaleImage)

Monday, January 2, 2012

Monitor AppFabric Cache Status Using PowerShell

While working on the AppFabric Cache feature for the current project, I create the following PowerShell script to monitor the AppFabric Cache status.

First, using following DOS command to start AppFabric Cache PowerShell environment in one of the cache host server:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "Set-ExecutionPolicy RemoteSigned;Import-Module DistributedCacheAdministration;Import-Module DistributedCacheConfiguration;Use-CacheCluster;Cd C:\\;Cls"

Second, assume the script MonitorAppFabricCache.ps1 is under C:\ folder, run following in PowerShell environment. It will generate the output at c:\AppFabricCacheStatus.txt and open the output:

.\MonitorAppFabricCache.ps1

Following is the content of MonitorAppFabricCache.ps1.

$AppFabricCacheStatusFile = "c:\AppFabricCacheStatus.txt"
Get-Date -format g | Out-File $AppFabricCacheStatusFile -Force
Out-File $AppFabricCacheStatusFile -InputObject "" -Append
Out-File $AppFabricCacheStatusFile -InputObject "" -Append
Out-File $AppFabricCacheStatusFile -InputObject "" -Append
Out-File $AppFabricCacheStatusFile -InputObject "Cache hosts status" -Append
Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
Get-CacheHost | Out-File $AppFabricCacheStatusFile -Append
Get-CacheClusterHealth | Out-File $AppFabricCacheStatusFile -Append
$CacheHosts = Get-CacheHost
foreach ($CacheHost in $CacheHosts)
{
    Out-File $AppFabricCacheStatusFile -InputObject "Cache host config - $($CacheHost.HostName)" -Append
    Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
    Get-CacheHostConfig -HostName $CacheHost.HostName -CachePort $CacheHost.PortNo | Out-File $AppFabricCacheStatusFile -Append
}
$Caches = Get-Cache
foreach ($Cache in $Caches)
{
    Out-File $AppFabricCacheStatusFile -InputObject "Cache statistics - $($Cache.CacheName)" -Append
    Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
    Get-CacheStatistics -CacheName $Cache.CacheName | Out-File $AppFabricCacheStatusFile -Append
}
foreach ($Cache in $Caches)
{
    Out-File $AppFabricCacheStatusFile -InputObject "Cache config - $($Cache.CacheName)" -Append
    Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
    Get-CacheConfig -CacheName $Cache.CacheName | Out-File $AppFabricCacheStatusFile -Append
}
Out-File $AppFabricCacheStatusFile -InputObject "Regions by cache" -Append
Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
Get-Cache | Out-File $AppFabricCacheStatusFile -Append
Out-File $AppFabricCacheStatusFile -InputObject "Regions by cache host" -Append
Out-File $AppFabricCacheStatusFile -InputObject "=========================" -Append
Get-CacheRegion | Out-File $AppFabricCacheStatusFile -Append
Invoke-Expression -Command $AppFabricCacheStatusFile