Author Archives: kenny

Eureka!

Limber Liger LogoLast weekend I dragged Lauren to San Francisco to play in Shinteki Decathalon, which is a miniature version of the crazy overnight games I’ve played in the past. Tom and Eric joined us to complete the “Limber Ligers”. It was a good time, we found out just how slow a paddle boat with four adults travels, and that the Fremont Open Space Preserve is not actually in Fremont, CA (though it does sport some nice views).

We came in a respectable 10th out of 23 teams, in spite of completely blanking on one of the puzzles. After reading this article I wonder if we would have done better by lying down to work on our puzzles and getting more “noradrenaline” into our brains. 🙂

Channels 102b: Close vs. Abort (vs. Dispose)

A major source of confusion with Indigo Beta 1 is how to shut down our communication objects, so I’m going to drill further into this topic. First, I must note that this area is under review for Beta 2. We understand there are some inconsistencies between our usage of IDisposable and its usage by other parts of the .Net Framework. But the CTP bits are what you have to work with for now, so I will do my best to explain them 🙂

When I talked about the common state machine in Indigo, I neglected to point out that ICommunicationObject derives from IDisposable. This gives you a third option (in addition to our Close() and Abort() methods) for shutdown. It also allows you to use any ICommunicationObject with the C# using statement.

In the CTP bits, Dispose == Abort. Or put another way, Dispose != Close. This is a point worth re-iterating. Dispose will rudely abort your object.

So when you are done with an ICommunicationObject, what should you do?

First you should call Close(), which will flush any outstanding buffers, acknowledge outstanding data, and provide a graceful shutdown. This is similar to what happens when you call Stream.Close() or XmlWriter.Close(). Then you should make sure that Abort/Dispose is called if anything fails (i.e. throws an exception). This way any heavyweight network resources are released in an eager fashion.

Which leads to code like the following:

IOutputChannel channel = CreateOutputChannel();

using (channel)
{

channel.Open();
channel.Send(message);
channel.Close();

}

Channels 102: Communication object lifecycle

Before we dive into implementing our Channels, it’s important to first understand the lifecycle of communication objects in Indigo. These include our Channel Layer objects (IChannel, IChannelFactory, and IListenerFactory), as well as Typed Layer objects (ServiceHost, ServiceSite, EndpointListener).

All such objects derive from ICommunicationObject, and have a common state machine.

There are 5 states represented by the CommunicationState enum:

  • Created — This is the state of an ICommunicationObject when it is first instantiated. The object may be configured in this state (e.g. properties can be modified, events registered, etc). No I/O occurs in this state.
  • Opening — Objects transition to this state when ICommunicationObject.Open() is called. At this point properties are made immutable, and I/O may begin. This transition is only valid from the Created state.
  • Opened — Objects transition to this state when the open process completes. This transition is only valid from the Opening state. At this point the object is fully usable for transfer.
  • Closing — Objects transition to this state when ICommunicationObject.Close() is called for a graceful shutdown. This transition is only valid from the Opened state.
  • Closed — In the Closed state objects are no longer usable. In general, most configuration is still accessible for inspection purposes, but no communication can occur. This state is equivalent to being disposed.

There are events that fire for each state transition. ICommunicationObject also has an Abort() method that can be called at any time. This will cause the object to transition immediately from its current state into the Closed state. Abort() indicates that any unfinished work will be rudely terminated (Exceptions are likely in this case).

With this background knowledge in place, we can now go into detail about writing our factories.

Tradition, tradition!

Lauren and I are hosting a (non-)traditional “8th night seder” on Saturday, and I’ve never made charoset before. So I e-mailed my Mom for the recipe and here was the response:

Apples, nuts and cinnamon, make charoset chop chop chop. Also wine, brown sugar vanilla extract if you want. Enjoy.

Love ya,
MOM

The thing I love most about family recipes is the exact proportions. 🙂

Channels 101: Get with the MEP

Last week I gave an overview of Indigo layering. In the next few posts I’ll guide you through these layers from the bottom up. We’ll start by writing a custom transport. Then we’ll add layered channels on top of this transport, and progressively work our way up the stack to a typed Service and Proxy implementation.

A fundamental concept at the Channel Layer is that of a Message Exchange Pattern (often referred to as “MEP”). There are three basic MEPs supported at the Channel Layer:

  1. Datagram: In this MEP, messages are “fire and forget”. It’s like when I send a postcard to my Mom. Just because I put the postcard in a mailbox does not mean that she received it. It may have gone to the incorrect address, or thrown out in the post office if she was on a long vacation, or eaten by a dog. I need to get any confirmation of successful delivery out of band (with a followup telephone call for example). Datagram is a fundamental building block for Messaging, as you can build arbitrary protocols on top of it (including reliable protocols, secure protocols, etc).

Datagram Message Exchange

  1. Request-Response: This is the most common MEP on the web today. It consists of a single message being sent, followed by a single response to that message. RPC calls are request-response, as are browser GETs. If I had paid for Delivery Confirmation on the postcard I sent my Mom, then I would have been using this MEP (with the confirmation as my response). This pattern is also known as half-duplex.

Request-Response Message Exchange

  1. Duplex: Duplex is equivalent to bi-directional datagram communication. Duplex communication is what we are used to in daily conversation. When I’m talking to a co-worker, we are free to speak at any time. We can comment at any time, and are engaging in an unrestricted ordering of “messages” between us. Note that delivery is still unreliable, and data can still be lost (if one of us is daydreaming or otherwise distracted).

Duplex Message Exchange

Each of these MEPs also have a session-ful variant. A session is an object that provides correlation for the MEP. Session is very useful for classifying data. It turns out that we use the concept of session constantly in our daily lives. Take as an example the conversations I have with my boss. As per our above definitions, when we converse we engage in Duplex communication. During a daily triage meeting we’ll talk about current issues for Indigo, and over lunch we’ll discuss the 520 commute. Each of these topics can be thought of as a session that subdivides our communication. While in the real world sessions often bleed into one another, in Indigo we can keep your session state localized to a given Channel. This gives you a total of 6 MEPs (Datagram, Request-Response, Duplex, Datagram+Session, Request-Response+Session, or Duplex+Session).

Some transports support multiple MEPs. For example, SOAP-over-TCP supports Datagram, Datagram+Session, and Duplex+Session. SOAP-over HTTP supports Datagram and Request-Response.

For our example, we are going to build a transport based on the User Datagram Protocol, so the MEP we will support is Datagram. The next step is to create an IChannelFactory and IListenerFactory to implement our Channels.

Spam Wars!

Senior year of college, I took a class on “Web Programming in Java”. One of the projects was to create a promotion site for a fictional movie. I came up with:

You need to have Java installed, and I apologize in advance if there’s a broken link at the end of a game (you may need to replace “zoo.cs.yale.edu:8000” with “pantheon.yale.edu”). If I can divine my old password to the system (I didn’t even realize the site still existed until today) I’ll try and fix it. Until then, have fun with some crazy Kenny Wolf humor.

Baking a Seven Layer Service Cake

Indigo is constructed with layering as a central design principle. This means that in essence Indigo is actually a collection of sub-frameworks, each of which can be supplemented by ISV code (or replaced completely for that matter). Each framework is defined by two things:

  1. Fundamental unit(s) of data
  2. Transformations that can be applied to said data

Which (as you might be thinking) is another way of saying an object is defined by its members and its methods. This is true, but it’s more difficult (but very important) to stay focused on consistent pivots when constructing clean frameworks.

MessagesIndigo is built around the concept of a Message object. The structure of a Message object loosely represents a SOAP envelope, and consists of two distinct parts: the message’s body and an extensible collection of headers. The body is application-defined data, and headers are added/processed by infrastructure (and can also be used by the application). Access to a header or the body is achieved through XmlReader, as it contains structured data. It is this structured primitive which is the core of Indigo’s power (and which departs from the classic networking primitive of a byte array). It allows for extensible, interoperable protocols to be built, and for data contracts to be established.

At a high level, Indigo consists of two larger frameworks: the Typed Layer, and the Channel Layer.
Indigo Architecture

The fundamental unit of data for the Channel Layer is Message. Channels are used to Send and Receive Messages. Channels come in two forms: Transport Channels and Layered Channels.

Transport Channels perform the actual send/receive of the Message to a network resource, including any necessary serialization.

Layered Channels perform a function based on the Message passed in, and then delegate further modification and transmission to their Inner Channel. So as you can see, even within a layer we have layers 🙂 Some examples of Layered Channels include Protocol Channels that use Message headers and infrastructure Messages to establish a higher-level protocol (such as WS-ReliableMessaging), and Reshaping Channels for changing the Message Exchange Pattern (such as converting an underlying [Send Channel, Receive Channel] pair into a Duplex Channel).

Message is a very flexible object, but to fully utilize it requires knowledge of Infosets and XML. What most developers instead will likely interface with is the Typed Layer. The fundamental unit of data for the Typed Layer is a CLR class. In the Typed Layer you create CLR objects that implement Services and Typed Proxies. The Typed Layer converts parameters and return values into Message objects and method calls into Channel calls. In this way, the Typed Layer builds on the functionality of the Channel Layer, and can transparently leverage any changes/improvements made to Channels.

Next I’ll provide an example to give you a flavor of this layering in action, stay tuned!