Partager via


Pull Not Push

There are two architectural models for moving messages through a system. Pull messaging models require the receiver to actively suck messages out of the pipeline in order to achieve flow. If the receiver is not willing to perform work, then there's nothing the sender can do to move messages around. Push messaging models automatically generate work on the receiving end when a sender transmits a message. It's then the responsibility of the receiver to process these work items before system capacity is reached (in many systems, there is some programming ease-of-use to make the work items automatically expire after some period of negligence by the receiver). Real messaging systems have many architectural layers stacked on top one another, some of which are push and some of which are pull. Just the process of sending a packet of data using TCP requires several protocol layers of pushing and pulling.

You may have noticed that the channel stack of WCF represents a pull model. Actually, you may not have noticed this because the service layer of WCF represents a push model. Even some parts of the channel stack push instead of pull. For instance, the arrival of new client connections at an endpoint is a push operation. Clients will attempt to connect even if the service is not ready to listen for them. However, the service has to engage in some pulling to transform those client connection attempts into transport channels. The boundary from a push layer to a pull layer is a queue. Quota settings on the queue define the system capacity for how much outstanding work is tolerated and how long work should wait in the queue before being expired. The boundary from a pull layer to a push layer is a message pump. Quota settings on the message pump define how aggressively the pump operates.

The channel stack uses a pull model because it's very convenient from a framework perspective. Pull models allow the user to explicitly control resources without having to define lots of complicated policy. Work only happens in a pull model when the user takes action, so the messaging system can simply idle when it doesn't have the capacity to accept additional work. Pull models are also convenient for error handling because there is always user code to which we can report any errors. If we don't have user code, then we need policy to dictate how errors are handled. Whenever you're writing channels, you need to keep the pull model in mind or else you will end up writing lots of fragile layer transition code as you go back and forth from push to pull. Try to normalize to pulling as low as possible in the stack.

Services use a push model because it's very convenient from a programming perspective. Nobody wants to write message pumping and dispatch loops. Programmers want to simply specify what their messaging handling logic is and let the system figure out when that logic should be invoked. Services normalize to the push model at the very top of the stack, above all of the channels.

Next time: Dealing with SSL Certificate Validation Failures

Comments

  • Anonymous
    November 06, 2006
    WCF has a variety of addressing controls for specifying where messages should be sent. For example, there's

  • Anonymous
    January 03, 2007
    I started this blog back in February hoping to produce a daily post throughout the entire month. I had