Welcome to MSDN Blogs Sign in | Join | Help

Syndication

News

Indigo
This posting is provided "AS IS"
with no warranties,
and confers no rights.

What to Measure?
Note: Cross posted from Sajay.
Permalink

    If it doesn't run fast at first, it will run even slower later.

image

Posted Friday, June 12, 2009 10:37 PM by Sajay | 0 Comments

Performance Testing for Web application - NeXpert
Note: Cross posted from Sajay.
Permalink

Here is a quick way to get an idea of how long your request/response takes and a ton of more data regarding your payload.

neXpert is an add-on to Fiddler Web Debugger which aids in performance testing web applications. neXpert was created to reduce the time it takes to look for performance issues with Fiddler and to create a deliverable that can be used to educate development teams.

Blog - http://blogs.msdn.com/nexpert/

Video- http://msdn.microsoft.com/en-us/dd573302.aspx - (4 minutes)

Download -http://www.microsoft.com/downloads/details.aspx?FamilyId=5975DA52-8CE6-48BD-9B3C-756A625024BB&displaylang=en

Introduction - http://blogs.msdn.com/nexpert/archive/2009/02/10/introducing-nexpert.aspx

Note: Cross posted from Sajay.
Permalink

Posted Tuesday, June 09, 2009 9:07 AM by Sajay | 0 Comments

The Channel Pump
Note: Cross posted from Sajay.
Permalink

Deep dive - Nicholas Allen's talk on WCF performance and Scale - PowerPoint Deck - Webcast

From the above talk you get an idea of the pull and the push model and a combination of these for certain channels. This defines how the message will be received on the transport and how they will be dispatched. Consider a pump as a loop doing some work. A pump works off a queue which it would push work on for the next layer or pulls work off when there is some work to be done.

Considering a very common scenario like basic http where a message would arrive on the transport. The flow would consist of 2 loops.

channel pump

Dispatcher/Message Pump

1. Dispatcher gets a message. It has available resources and will dispatch the operation(Application)
2. Dispatcher then tells the pump that it can accept the next message.

Channel Pump

1. Pump registers that it can take pull a message.
2. Message arrives and Transport pushes the message to the dispatcher.

All channels affect how messages arrive and how they would be dispatched. We make a fundamental assumption in WCF that channels would always be fast. This is because of the fact that the channel is your infrastructure and it makes sense to put any heavy work to the application layer and not the channel layer.

So general rule of thumb - Do not do blocking or heavy work in your channels. Pass on the work to the upper application layer.

You should think of your channel as gate to your dispatcher and you don't want to block the gate from letting the next person in. Hence bottom line is that a slow channel is a suboptimal channel.

Posted Tuesday, June 09, 2009 9:04 AM by Sajay | 0 Comments

AsyncResults and IAsyncResults
Note: Cross posted from Sajay.
Permalink

Here is a deep dive on of how to implement your AsyncResult

Quick Pointers 

Posted Tuesday, June 09, 2009 9:02 AM by Sajay | 0 Comments

How to use an AsyncResult?
Note: Cross posted from Sajay.
Permalink

I have a much longer article in mind for this and will be publishing it out soon. But to quickly answer this let us use an implementation from the framework itself using a delegate. Please note, this is for a usage pattern sample only since all that a delegate does is put the work on the CLR's thread pool which means more latency for non-blocking work. ...

Posted Tuesday, June 09, 2009 9:01 AM by Sajay | 0 Comments

Lock Free iterator
Note: Cross posted from Sajay.
Permalink

Most common data structures are usually meant for single threaded access and queues are no exception. When there are multiple producers writing to the queue we usually need to make sure that the writer is given a unique index that he can put the element into. If our operations are synchronized already and thread safe we can do something like this 

public void Enqueue(T item) 
{  
    ...  
    tail = (tail+1) % size;  
    items[tail] = item;  
}

On the other hand if 2 threads simultaneously got to the highlighted line then they could even overwrite each other if the read the value of the tail at the same time. Now what are the issues we face.

  1. The read might be stale.
  2. One thread might get an old value and corrupt state.
  3. The value of the tail is corrupted and would not actually get incremented for each thread.

We could consider using Interlocked increment and get away with something like this

public void Enqueue(T item) 
{ 
    int next = Interlocked.Increment(ref tail) % size; 
    ... 
    items[next] = item; 
} 

Hmm this doesn't seem right. Well the issue is the wrap around behavior for interlocked.Incremement. Once it reaches Int32.Max value it then gets back to Int32.Min value and then on it's pretty much useless as the next count would read something like (Int32.MinValue%size) wiz quite a an odd value. For example for size 100 we could end up with indexes like this

. 46,47,-48,-49

Lets look at another approach which is CompareExchage. Some fundamentals about Interlocked.CompareExchange

  1. It returns the latest value for the location.
  2. It will exchange the value if it matches the comperand atomically. 

From this we can deduce that if a thread tried to increment a value and failed then someone already updated it. This also means that we might not succeed in a single try and hence would need to retry until till we successfully get a slot which we will own. The fact that we were able to increment it also means that no other thread will get this slot. So now lets look at the implementation.

class LockFreeCircularIterator 
{
  int index = 0;
  readonly int limit;
  
  public LockFreeCircularIterator(int limit)
  {
    this.limit = limit; 
  }
  public int GetNext()
  {
    int slot = this.index;
    while(true)
    {
      if(slot == (slot = Interlocked.CompareExchange(ref this.index, (slot+1) % limit, slot)))
      {
        return slot;
      }
    }
  }
}

Here we see that we iterate till the index was updated with the incremented value. Each time it failed the new value of the index was read and attempted again. This was one of the implementations of the iterator. This allows multiple threads to write to a circular buffer. I'm omitting the usage as there are quite a few places this could come in hand.

Posted Tuesday, June 09, 2009 9:00 AM by Sajay | 0 Comments

Find processes that have open handles to your files - Powershell
Note: Cross posted from Sajay.
Permalink

This seemed like a really nice mix of handle.exe from sysinternals and powershell.

Check out the script at http://msgoodies.blogspot.com/2009/03/get-openfile.html

Update fix for get-process piping

You have to remove the '.exe' from the output from handle.exe to get it working to pipe it to gps.

param($fileFilter=$(throw "Filter must be specified"))
c:\sysint\handle.exe $fileFilter | foreach {
    if ($_ -match '^(?<program>\S*)\s*pid: (?<pid>\d*)\s*(?<handle>[\da-z]*):\s*(?<file>(\\\\)|([a-z]:).*)') {
        $matches | select  @{n="Path";e={$_.file}},@{n="Handle";e={$_.handle}},@{n="Pid";e={$_.pid}},@{n="ProcessName";e={$_.Program.Replace(".exe","")}}
        }
}

Posted Tuesday, June 09, 2009 8:59 AM by Sajay | 0 Comments

How can I create a binding instance from a configuration name?

Bindings (such as BasicHttpBinding, WSHttpBinding etc.) have a have a constructor that take the configuration name. You need to know the type of binding as the name themselves are not unique across different binding sections.

Posted Tuesday, June 09, 2009 8:58 AM by Sajay | 0 Comments

WCF Configuration Manager
Note: Cross posted from Sajay.
Permalink

Finally after about 3 releases of WCF we got a configuration service sample on MSDN. I haven't exactly played with the bits myself but did get a good review from some folks who wanted to use it for service management. This does allow a degree of configuration management for your WCF services and I believe can even be backed up to a datastore.

http://msdn.microsoft.com/en-us/netframework/bb499684.aspx 

  • Configuration Service 2.03 is a reusable set of shared libraries that provides central configuration management for .NET applications, ASP.NET Applications, and WCF service hosts. It provides the ability to cluster multiple nodes, with load balancing and application-level failover across remote nodes; as well as a centralized configuration management user interface, cluster and endpoint status monitoring, and dynamic configuration updates across clusters without having to deploy new configuration files or stop/start active nodes.

 

  • The Configuration Service was born out of a practical need to make it easier to manage the .NET StockTrader composite application in distributed, clustered environments. The concepts were then abstracted such that any .NET application/WCF service host can implement the Configuration Service via the shared libraries provided. This is possible based on the use of base classes and .NET reflection within the shared libraries. For those familiar with WCF, it should only take a few hours to walk through the tutorial and test it out. It is designed such that existing WCF services can easily be integrated into a WCF service host (IIS, Windows Application, Console Application, or Windows NT Service) that implements the Configuration Service.

And yes there is a stock trader application along with it :).

Posted Tuesday, June 09, 2009 8:57 AM by Sajay | 0 Comments

Speaking at Techready

*** MOVED to http://www.sajay.com/post/2009/02/05/Speaking-at-Techready.aspx

 

This was my first time presenting at Techready . Being a part of the performance dev team in WCF, this would be a natural topic to pick up. The audience was great and we were aware of some of the problems they mentioned and hoping to solve them in the upcoming releases of the framework.  Wenlong gave a pretty deep insight into the guts of the WCF pumps and throttle's and I walked through some of the common scenarios we have discussed with customers and some demos on the tools we use and recommend.

 

image

Next time - A whole view of the WCF Pump.

Posted Thursday, February 05, 2009 3:29 PM by Sajay | 1 Comments

Tips on matching you Bindings

Have you ever tried to get CustomBindings equivalent to a StandardBinding or vice versa. Well recently I was asked why a customBinding  like

<customBinding>
  <
binding name="Custom">
    <
textMessageEncoding />
      <
security authenticationMode="UserNameOverTransport">
         <
secureConversationBootstrap />
      </
security>
    <
httpsTransport />
  </
binding>
</
customBinding>

was not similar to a wsHttpBinding like the following

<wsHttpBinding>
  <
binding name="WS">
   
<security mode="TransportWithMessageCredential" />
  </
binding>
</
wsHttpBinding>

They do look similar but there are subtle aspects which which probably make them really different. I am not going to call out every difference here and will leave it to you to spot them. The major point here is that this choice can either make or break your app primarily since I work on perf here and choosing the second would be quite a blow to perf if you really don't want the bells and whistles that wsHttpBinding provides, sometimes 4 to 5 times.

Posted Thursday, February 05, 2009 10:00 AM by Sajay | 0 Comments

Softwear!!!!

Note: this entry has moved.

image 

There is no way you can not remember the days when you though TSR's were cool.
http://adage.com/agencynews/article?article_id=133069

Posted Saturday, December 06, 2008 6:22 PM by Sajay | 0 Comments

The EventLog and Message limits

Note: this entry has moved.

Sometimes I have to fix certain issues in BizTalk and during one of these exercises I had to write a large message into the eventlog.OUCH! Ok now who does that ? Well I’m not at fault here but then again we did require this for some convoluted reason. Anyway there was some whacky boundary condition code. So to get a quick value just decided to flood my event log and see how much can it store.

        static void Main(string[] args)
        {
            int limit=31000;
            int source = 10; //212 is the limit here.
            while(true)
            {
                try
                {
                    SD.EventLog.WriteEntry(new string('s',source) , new string('v', limit), System.Diagnostics.EventLogEntryType.Information, 0, 0);
                    limit++;
                }
                catch (Win32Exception ex)
                {
                    Console.WriteLine(--limit);
                    break;
                }
            }

            SD.EventLog.WriteEntry(new string('s', source), new string('v', limit), System.Diagnostics.EventLogEntryType.Information, 0, 0);
            Console.WriteLine("Total = " + (source + limit));
        }

And guess – its a magic number 31884  and not 32k. System.Diagnostics.Eventlog actually uses advapi32!ReportEvent but this seems to have a 32k limit. Anyway short answer is that its not “exactly” 32k.

Posted Wednesday, December 03, 2008 12:48 AM by Sajay | 0 Comments

Filed under: ,

Bird is leaving the blogs.msdn.com nest

After quite a lot of hard work I finally managed to move and aggregate stuff and so have moved onto http://sajay.com. What even was or would have been here is now at http://sajay.com/category/Microsoft.aspx 
RSS feed for MicrosoftMicrosoft (68)

Thats all folks.

Posted Tuesday, November 04, 2008 8:08 PM by Sajay | 1 Comments

Filed under:

Synchronous execution in WF

My previous post points to those of you who want a first look at WF 4.0.

This post focuses more on how to get one of the best Async Runtimes to get executed in sync(shooting myself in the foot here). This was inspired by a question from a friend of mine who wanted to play with the gory stuff like TLS and other unmentionables. For people already working in WF 3.X you would be familiar with the Manual Workflow Sheduler Service. If not then to sum it up its a way to run your activity synchronosly.

That being said I am not sure on how familiar you are with the little known but very cool SynchronizationContext that got introduced with 2.0. WF leverages this to solve this fundamental problem.

I would like to first explain using the default sync context in a winform app to showcase how to avoid invoke calls when updating your control text using a workflow.

using System.Windows.Forms;

using System.Threading;

using System.WorkflowModel;

 

namespace WinformTest

{

    class Program

    {

        static void Main(string[] args)

        {

            Application.Run(new MyForm());

        }

 

        class MyForm : Form

        {

            SynchronizationContext ctx;

            Button button;

            public MyForm()

            {

                ctx = SynchronizationContext.Current;

                button = new Button();

                button.Click += new System.EventHandler(b_Click);

                this.Controls.Add(button);

            }

 

            void b_Click(object sender, System.EventArgs e)

            {

                ChangeText we = new ChangeText();

                we.form = this;

                WorkflowInstance instance = WorkflowInstance.Create(we, this.ctx);

                instance.Resume();

            }

 

            class ChangeText : WorkflowElement

            {

                public MyForm form;

                protected override void Execute(ActivityExecutionContext context)

                {

                    form.button.Text = "Changed";

                }

            }

        }

    }

}

Now where did that control.Invoke call disapper. Thats where SynchronizationContext kicks in.
To show a simple sync context for synchronous execution you could just pass in your own Sync context as below.

Here the idea is to set a value on the TLS and execute a workflow with and without the context and showcase what value comes of the TLS in each case.

using System;

using System.Threading;

using System.WorkflowModel;

 

namespace SyncContextSample

{

    class Program

    {       

        static void Main(string[] args)

        {

            DataItem.id = Thread.CurrentThread.ManagedThreadId.ToString();

            DataItem.DisplayData();

            ExecuteWorkflow();

            Console.ReadLine();

        }

 

        private static void ExecuteWorkflow()

        {

            DataItem.id = Thread.CurrentThread.ManagedThreadId.ToString();

            DataItem.DisplayData();

            SynchronizationContext context = new SynchronousSynchronizationContext();

 

            WorkflowInstance instance = WorkflowInstance.Create(CreateRootActivity(), context);

            instance.Resume();

 

            WorkflowInstance instance2 = WorkflowInstance.Create(CreateRootActivity());

            instance2.Resume();           

        }

 

        public static WorkflowElement CreateRootActivity()

        {

            return new DipslayTLS();

        }

    }

 

    public class DipslayTLS : WorkflowElement

    {       

        protected override void Execute(ActivityExecutionContext context)

        {

            Console.WriteLine("Executing Activity");

            DataItem.DisplayData();

        }

    }

 

    public class DataItem

    {

        [ThreadStatic]

        public static string id;

 

        public static void DisplayData()

        {           

            Console.WriteLine("Thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId + " has data: " + id);

        }

    }

   

    public class SynchronousSynchronizationContext : SynchronizationContext

    {

        public SynchronousSynchronizationContext()

            : base()

        {}

 

        public override void Post(SendOrPostCallback callback, object state)

        {

            callback(state);

        }

 

        public override void Send(SendOrPostCallback callback, object state)

        {

            callback(state);

        }

    }

}

 

You would get something like this

Thread: 1 has data: 1
Thread: 1 has data: 1
Executing Activity
Thread: 1 has data: 1
Executing Activity
Thread: 3 has data:

Just as note this is more of rare case and should be used only when you know you need it cause you loose all the benefits of going totally async and taking advantage of the WF 4.0 runtime robustness.

 

Posted Wednesday, October 29, 2008 5:40 PM by Sajay | 0 Comments

Filed under:

More Posts Next page »
Page view tracker