Image

One of the key tasks that every RFID application has to perform is managing the flow of information from the RFID devices. BizTalk RFID includes a brand-new application model for robust, low-latency event processing. This application model streamlines the handling of common tasks related to event processing applications, in the same manner that ASP.NET has streamlined the process of authoring web pages. Just like ASP.NET, the event processing model includes a description of the application, the ability to incorporate custom components from third-party software vendors, a hosting model, and deployment and configuration support.

This chapter will examine different aspects of the application model, including the design-time experience, the binding and deployment experience, and how to monitor and troubleshoot RFID applications.

This chapter begins with a brief overview of the application model using a very simple scenario. This is followed by a set of exercises designed to get your hands dirty with the specifics of the model. Finally, it concludes with detailed topic-by-topic descriptions of the aspects of the model.

If you want to see the detailed explanations before you dive into the exercises, you can skip the exercises and come back to them at the end.

What Is a BizTalk RFID Process?

A BizTalk RFID process (or an RFID process, for short) is a declarative model for specifying the flow and format of event processing. It is declarative in the sense that the definition of an RFID process is expressed through an XML-based description, rather than through C# or VB .NET code. As a declarative model, it is similar to both the BizTalk Server definition of orchestrations and pipelines and the Windows Workflow Foundation (WF) XOML definition of a workflow. Just like a WF workflow is the model that stitches a set of activities together, the RFID process defines the order in which a pipeline of EventHandler components should be executed for a given event.

The original intent and design of RFID processes have always been focused on enabling low-latency, large-volume event processing. This focus is what differentiates the RFID process from other model-based workflow descriptions. Once an RFID process is created and deployed into BizTalk RFID, it should be thought of as a distinct background service that is hosted by BizTalk RFID. These RFID processes run within the RFID background service, and have no direct interaction with the desktop. While an RFID process can be designed to accept user input, these types of scenarios are generally better served through the use of a synchronous application (as described in Chapter 6), or through external messaging/queuing approaches.

To illustrate how an RFID process works, let’s walk through a small scenario, pictorially depicted in Figure 5-1. Assume a warehouse with a single exit gate equipped with an RFID reader, and that goods leaving the warehouse through this gate have an attached RFID tag at both the pallet and case level. The goal is to automatically generate outbound shipment confirmations as pallets leave the warehouse. You can do this with an RFID business process, where you will collect real-time business-relevant information automatically, and send it to a back-end server for processing. Once you have installed and configured the RFID process that implements this “automatic” workflow, it needs to run without interruption or requiring manual user input.

Image

Figure 5-1. Pictorial description of a shipment confirmation scenario

The physical deployment for this scenario is outlined in the physical deployment architecture in Figure 5-2. Typically, the RFID reader will be connected to the BizTalk RFID server using a network connection.

Image

Figure 5-2. Physical deployment architecture for the shipment confirmation scenario

The logical flow of events for this scenario is depicted in Figure 5-3.

Image

Figure 5-3. Logical event flow for the shipment confirmation scenario

To implement this scenario, there are five key elements to the BizTalk RFID process application model:

The XML description of the process: Typically called the RFID process definition, this describes the paths that will be taken by the different event types at runtime, and the EventHandler components, which are individual units of code that will be invoked to actually handle the event. Each segment of processing, including the sources of events and the event handlers that will process the events sequentially, is called a logical source. The logical source may be thought of as a pipeline segment for event processing. Every RFID process has at least one logical source. The logical source can itself be composed of child logical sources— other pipeline segments that feed into the parent logical source. This allows a sophisticated event processing tree to be built up out of individual pipeline segments.

The EventHandler: This is a fragment of .NET code capable of receiving events in the context of an RFID process. Within an RFID process, events are passed through a chain of EventHandler components. Each EventHandler class adheres to a specific contract that defines how various types of events are sent and received, as described in the “Event Processing Application Model” section. For your simple shipment confirmation scenario, assume that you have an EventHandler component called CreateShipmentConfirmation that transforms RFID events into a shipment confirmation notice. The declarative nature of the RFID process model and the formal contract implemented by EventHandler components allow you to plug this functionality into any other business process that requires this functionality in a reusable fashion.

The store-and-forward abstraction: This completely decouples the events from the physical RFID devices that raised the events. BizTalk RFID introduces the concept of a logical device to deliver such events to the business process.

The logical device: Logical devices are “virtual” readers that are used to provide a link between physical devices and processes, as well the ability to group readers and sources by their logical function. Logical devices have a name and are bound to a set of real devices at deployment time (of the RFID process). Using logical devices, rather than directly connecting physical event sources, allows the complete separation of design-time and deployment-time concerns. Additionally, it allows the same process definition to be reused across different physical topologies.

Binding: This is the process of associating the business process with real readers and antennas, which ensures that events are actually delivered to the process. In the preceding scenario, the gate reader is a logical device that is bound to the physical readers on the warehouse exit door. When designing the RFID process, the exact physical RFID configuration to be used may not yet be known (e.g., one reader with four antennae, two readers with two antennae each, etc.). Without having all of this information in advance, you still need a method of assigning a collection of event sources into a logical group (i.e., a logical device).

To summarize, the design-time support, reusable components, and flexible deployment possibilities are the key value propositions behind the RFID process model. It allows developers and third-party vendors (independent software vendors, or ISVs) to create event handler libraries that can be reused across a variety of business scenarios and RFID processes. The EventHandler is the fundamental extensibility mechanism exposed by BizTalk RFID for event processing. All of the samples and scenarios presented in this book, including integration scenarios with external systems such as the Business Rule Engine (BRE) and Business Activity Monitoring (BAM), will be performed using EventHandler components.

Hands-On Exercises

Now that we’ve looked at the theory, Exercises 5-1 through 5-5 will look at how you can author RFID processes in practice. The RFID process is typically defined using RFID Manager and the process-creation Bind wizard. RFID process definitions may also be created in .NET or via direct XML definitions, but these are generally more difficult and error-prone methods. Finally, once you have created an RFID process, you can export the definition as XML and import an existing definition using RFID Manager or the command-line console client.

Exercise 5-1. Creating an RFID Process That Uses Out-of-the-Box Event Handlers

Exercise 5-2. Binding a Logical Device to a Physical Device

Exercise 5-3. Sending an RFID Tag Read Event to the Process

Exercise 5-4. Creating a Custom Event Handler and Adding It to the Process

Exercise 5-5. Creating an RFID Process Programmatically

Event Processing Application Model

In this section, we will look in detail into the various components of the event handler contract and the optional behaviors that your event handler can implement, including advanced features such as deployment support.

Initialization

The event handler must derive from the RfidEventHandlerBase class, which has abstract methods for initializing and disposing event handlers. You must override the Init method in your subclass to perform any initialization needed. The signature of the Init method looks like the following:

        public override void Init(
Dictionary<string, object> parameters,
RfidProcessContext container)

The first argument is the list of parameters that are used by this event handler. (If you’re wondering how BizTalk RFID knows what the parameters for your particular event handler are, and how a user can specify them, this is described in the “Design-Time Support” section, which follows.) The last argument is the current RfidProcessContext, which is an application-wide context object. You don’t need to hold on to a reference to this context, since it is also always available from the Current property on the RfidProcessContext.

Design-Time Support

Every event handler must implement a static method with this exact signature:

       public static RfidEventHandlerMetadata
           GetEventHandlerMetaData(bool includeVendorExtensions)

This method returns information about your particular event handler, including the number of parameters, their types, their descriptions, whether they are mandatory, and so on. This information is used in two fundamental ways. The first is when your event handler is in design time (i.e., when a process author is trying to add your component to an RFID process, the metadata is used by the designer to create a property grid for your event handler). The second is internally by the runtime when it has to initialize your component. It uses the metadata to confirm that the bindings for the component are consistent, and ensures that the types are correct and all mandatory properties are specified and present.

ImageTip You should consider the includeVendorExtensions Boolean to determine which scenario is in play: you may have some extra information that is potentially of use to the component configuration experience for the user interface only. For example, if you drop a RuleEnginePolicyExecutor event handler into a process definition, you will notice that it has a drop-down of all the available policies in the system, from which you can pick one. This information is useful at design time but not at validation time, and it may potentially be expensive and wasteful to compute and throw away. In such scenarios, use the includeVendorExtensions Boolean to determine if the extra information needs to be populated in the metadata dictionary and returned to the caller.

The Actual Event Handler Methods

Your event handler class can contain one or more methods annotated with the [RfidEventHandlerMethod] attribute that are used to actually handle the events. Delivery of the events is managed automatically by BizTalk RFID, and your method will be invoked when the event of the appropriate type arrives. A typical event handler method signature will look like this:

        [RfidEventHandlerMethod]
        public ShipmentEvent TransformToShipment(TagReadEvent tre)

Details of the semantics of the attribute and the implicit type checking are discussed in the “Strong Typing” section, which follows. For now, keep the annotation in mind, as well as the fact that your method is really one link in the pipeline of event processing. If you want to stop processing the event, there are two possible times to do this: at compile time and at runtime. At compile time, if your method returns void, then it is explicit that there can be no downstream event handlers, and your component is the end of the road for that particular event. At runtime, if your method returns null, BizTalk RFID assumes that you want to filter the current event, and stops event processing.

A general rule of thumb is to minimize the execution time inside your method, and not perform any long blocking operations within it. Remember, the rest of the RFID process infrastructure is lightweight and low-latency, but once it calls your code, you are holding precious resources that will affect the scalability and performance of the system. If you need to access a database, make every effort to have the database local to the edge server. It is usually a bad idea to hold onto local resources and make a call from the edge to a remote location, since the remote call could take a long time to execute. If your event handler takes a long time to execute, BizTalk RFID will give up on it and treat it as an error condition. (Error handling is covered in detail in the “Error Handling” section.)

Tear-Down and Cleanup

The event handler contract supports the standard .NET IDisposable pattern. If your class implements IDisposable, the runtime will invoke it when the process is being shut down. To help you implement IDisposable correctly, the base class includes an overridable implementation of Dispose. We strongly recommend the following pattern for disposing of objects. For excellent discussions on the topic, search for “IDisposable” on MSDN.

protected override void Dispose(bool disposing)
{
    try
    {
        //cleanup
    }
    finally
    {
        base.Dispose(disposing);
    }
}

Deployment and Undeployment

This part of the contract for an event handler is optional. If your event handler is completely self-contained (e.g., if it is a parser of some encoding), you may not need any installation support for it. On the other hand, most complex real-world event handlers need some level of installation support. For example, the SqlServerSink component that ships with BizTalk RFID needs to create the SQL database and the schema that it needs. If your event handler requires such deployment support, implement the following static method with this exact signature:

public static void Deploy (Dictionary<string,Object> parameters)

This method will be invoked each time the process containing it is deployed. The parameters dictionary will contain the same parameters that were specified in the metadata for your component.

ImageTip If you have an event handler that is potentially used in multiple RFID processes (and to be fair, most are), the Deploy method could be called multiple times with the same set of parameters, even concurrently. If you are performing external initialization, such as creating a database using the set of parameter values, ensure that the method will not fail if another invocation has done the initialization already.

The event handler deployment usually runs under the security context of the user running RFID Manager, which is typically a box administrator. This is because most deployment operations (e.g., creating databases) will require extra permissions than those available to the account that is executing the RFID process at runtime. However, during deployment, you may need to access the identity of the runtime user so that you can grant that user the runtime permissions needed. For this reason, the “process runtime user” is passed in as a special key to the Deploy method. You can access the value at this key by using the ProcessRuntimeUserKey property on the ProcessBinding.

If complementary uninstallation must happen when your component is no longer being used, you can implement another static method with the following signature:

public static void Undeploy(Dictionary<string, object> parameters)

ImageCaution Unlike Windows installers, the Undeploy method does not check whether no other processes are using the same state that this instance is using. You need to be very careful when you throw away state (e.g., when dropping a database) in the Undeploy method. For this reason, there is no support to invoke the undeploy functionality from within RFID Manager. You have to use the rfidclientconsole.exe command-line tool or actually create a small program that you launch directly to do this.

Strong Typing

When users first started creating RFID business processes using beta versions of BizTalk RFID, we noticed a common issue that they ran into: they would compose pipelines of event handlers and run events through them, and nothing would happen. The code in their event handlers never got invoked, and they had a really hard time figuring out why. The problem was, you could have event handlers that wanted to completely handle the event, and would not want to pass them on to the next event handler. The out-of-the-box SqlServerSink event handler is an example of such an event handler, and making it the first component in the pipeline was the usual way that this problem would crop up. Another common issue that users ran into was that no one really knew if an event handler would work until runtime. This was because there was no information available about the kinds of types that the current event handler could consume, nor about the types of events that the previous event handler would produce. Metaphorically speaking, an event handler could return a square peg, and the second would expect a round hole, and you would not be able to tell until the event was delivered to the event handler, by which time it was typically too late.

The strong typing feature in the event processing pipeline robustly addresses both of these common problems in the following way: each event handler in the pipeline describes the types that it consumes and the types that it produces. Given that, the pipeline definition can be “compiled,” from a type safety perspective, as part of the deployment of the process into BizTalk RFID. This operation is very similar to the type checking that happens in C#, for example. While introducing this feature, one constraint that had to be supported was the ability to define multiple event handling methods within a single class, and not require the user to define a class for each kind of event they wanted to handle. The solution to this problem was to use a custom attribute to indicate which methods were RFID event handler methods. Consider the following example:

public class HelloWorld: RfidEventHandlerBase
{
    [RfidEventHandlerMethod]
    public void DoSomething(TagReadEvent tre)
    {
    }

The [RfidEventHandlerMethod] custom attribute is used to indicate the method DoSomething as being special, and capable of being used in an RFID process pipeline. If you have used the [WebMethod] annotation to indicate the methods on a web service, or [OperationContract] to indicate the operations on a WCF service, this is exactly the same kind of pattern, where the custom attribute is used as an out-of-band annotation. Further, the C# signature of the method is used to determine the input and output types for the method. In this case, the method consumes a TagReadEvent, and its return type is void (i.e., it does not return anything). If you try to compose an event handler pipeline where this is the first one in the pipeline and another method comes after it, the validation of the process will fail.

There are a couple of really interesting implications of this model:

  • Instead of forcing you to implement a method with a particular signature, it lets you define methods that can have any name that is meaningful to your scenario. For example, instead of calling the method DoSomething, you could call it PostToFile, if that is what the event handler did.
  • If you have a custom event that derives from RfidEventBase or one of its subclasses, you could use that in your signature directly instead. This gives you a completely strongly typed experience, with full inheritance support inside Visual Studio.

For example, here is a definition of a custom event called MyCustomEvent:

public class MyCustomEvent: RfidEventBase
{
    private string property;
    private string secondProperty;

    public string Property
    {
        get { return property; }
        set { property = value; }
    }

    public string SecondProperty
    {
        get { return secondProperty; }
        set { secondProperty = value; }
    }
  }

Here is an event handler method that takes a tag read event, does some lookup and transformation, and returns a MyCustomEvent:

[RfidEventHandlerMethod]
public MyCustomEvent Transform(TagReadEvent tre)
{
    MyCustomEvent result = new MyCustomEvent();
    //to-do: transform the tag read into a custom event
    return result;
}

Next, let’s look at how strong typing affects operations during execution time:

  • It will implicitly filter events based on the method signature. At execution time, BizTalk RFID will automatically collect the list of types that are understood by your process, and ensure that only events of those types are delivered into your process. All other event types are filtered automatically. This helps avoid an entire class of runtime and type mismatch errors that would otherwise have to be handled by your event handler.
  • If your event handler is the first event handler in the pipeline, and it takes a TagReadEvent, and a provider raises a TagListEvent, the runtime will automatically “shred” the list into individual events and run them through the pipeline one at a time. However, if the first event handler is actually a TagListEvent, the runtime will not shred the list. The converse is not true—if your pipeline accepts TagListEvents, and a TagReadEvent is posted, the runtime will not convert the single event into a list.
  • If one event handler returns an object of the super type—say, RfidEventBase—and the second event handler takes a subtype—say, MyCustomEvent—a runtime cast operator is applied, and the event processing is aborted if the cast fails.

There are many more such interesting rules, and enumerating all of them exhaustively is not something we are trying to do in this section, but we hope you are left with a good idea of what strong typing is and how it benefits you.

ImageTip BizTalk RFID tries its best to ensure that processes in the store are always in a validated state (i.e., they compile successfully). The only exception is intermediate, or “work-in-progress,” process definitions created using RFID Manager. In the rare event that you need to implement and validate your own process, you can use the following methods in the ProcessManagerProxy class:

    ProcessManagerProxy pmp = new ProcessManagerProxy();
    RfidProcess process = pmp.GetProcess("MyProcess");
    pmp.SaveProcessWithoutValidation(process);
    pmp.ValidateProcessAndBinding(process.Name);

You can validate a process only if it is not running. Use the GetProcessStatus method on the ProcessManagerProxy object to determine if the process is running, and stop it first if you need to.

Error Handling

BizTalk RFID considers the event handler to have raised an error if any of the following conditions are true:

  • The event handler initialization takes more than the permitted time.
  • The event handler method itself takes more than the permitted time.
  • The event handler method throws an exception.

Each time an event processing sequence ends in an error, the information is accumulated within the runtime. If the number of errors exceeds a specified percentage of the last 100 events processed, the entire RFID process is deemed to be in a faulty state, and is restarted.

The percentage of tolerable errors and the values of the knobs for maximum event processing time are settable on the ProcessBinding object, and also through RFID Manager (see Figure 5-29).

Image

Figure 5-29. Changing the error handling properties for an RFID process

ImageTip The default value for error handling threshold is 0 (i.e., restart on the first error). This could cause the process to restart perpetually when you are developing your event handler and make it hard to debug. Set the value to a high number for development.

You can view the last error encountered by a process on the hub page for the process in RFID Manager. Pay close attention to the time at which the error was reported—there is no way to clear the error information in RFID Manager, and you could be chasing a problem that happened three days ago!

As a rule of thumb, you should handle all “recoverable” errors within your event handler, and take the appropriate actions. If the exception condition is truly exceptional, and the action to be taken is not known, it is best to let the BizTalk RFID runtime handle the exception.

If your event handler creates background threads for any tasks, and you want to plug into the error handling policy infrastructure even for those threads, you can use the ReportError method on the RfidProcessContext object:

         RfidProcessContext.Current.ReportError("my custom error");

Remember, you only need to do this for custom tasks that you schedule through the thread pool yourself, or for threads that you create and manage. For all exceptions on the event handler method itself, this extra step is not needed.

At first glance, this sounds like a lot of machinery to handle an error, but it is actually quite flexible once you get used to it. It lets you create very flexible policies that let you keep running while in development and debugging, and also decide on a pragmatic policy for production deployments. You don’t really want to wake up your system administrator if one event fails processing at 3:00 a.m., but you also don’t want a process to be “running” but failing all event processing with an error (e.g., you may not be able to write an event to a database once a day, which could be tolerable, but if no events are getting persisted because the database is down, you may want to page your administrator). This level of control ties in naturally with the monitoring and production deployment guidelines that are covered in Chapter 11.

Binding and Deployment

Now you have created a process, and it contains event handlers and logical devices. In this section, we will walk through the process of binding logical devices to real devices, and assigning valid parameter values to all the event handlers in the process. Both of these pieces of information are collectively referred to as the process binding, and the ProcessBinding object is a top-level object in the BizTalk RFID ProcessManager API. Before an RFID process is usable, you must associate a binding for it. Just like authoring RFID processes, binding is best accomplished through RFID Manager, either through the Bind wizard or the right-click Bind menu option on the logical device inside the process. However, you are going to do it the hard way, through the BindingManager API, to ensure you understand all the steps that RFID Manager is taking under the hood.

Binding Logical Devices to Physical Devices

Logical devices are application-level names that have some application semantics that are potentially used in the code of the event handler. For example, a logical device named ExitGateReader can let you write code to say, “Whenever an object is read by the exit gate reader, perform exit checks.” You would hate to change your code just because the physical reader name is different in a deployment. This is why it is important to use logical devices wherever possible in your code, and not have references to any deployment artifacts.

When you bind a logical device, you must designate a physical source of events that will be hooked up to it. This physical source could come in one of four ways:

  • You could bind a logical device to a particular physical device, using the friendly name of the device.
  • You could bind a logical device to a device group, in which case events from all the members of the group (and its subgroups transitively, if any) would be routed to your logical device.
  • You could bind an antenna of a physical device to a logical device (i.e., just events from a single source would be delivered to your logical device).
  • You could use a regular expression, and all friendly device names that match that regular expression would route events to your logical device.

From the preceding choices, you should notice that a logical device can be less than, exactly the same as, or more than a physical device. This flexibility lets you take a process and deploy it in a number of physical topologies without having to redesign. For example, in a really small warehouse station, the ExitGateReader may just be an antenna. In a large warehouse, it may be a bank of readers aimed at all the doors. You can use the binding step to achieve this flexibility.

ImageTip Both device groups and regular expression bindings have the flexibility that you are binding not to a particular device, but to a collection of devices. This indirection provides you with the flexibility to change the membership of the collection in an online fashion without stopping the process and redeploying bindings. Changing the group membership will automatically cause devices to get opened and closed depending on the processes that are bound to them. If you explicitly bind to devices or device sources, you don’t have this flexibility. You cannot drop or change the device name as long as a process has an explicit reference to it. Look at the hard links concept in the BizTalk RFID documentation for a precise explanation of the semantics of these links.

ProcessBinding binding = new ProcessBinding();
binding.DeviceBindings["ExitGateReader"] = new DeviceBinding();

//bind a group, a device, an expression, and a source
//to this logical device
            binding.DeviceBindings["ExitGateReader"].DeviceGroupList.Add("MyGroup");
            binding.DeviceBindings["ExitGateReader"].DeviceList.Add("MyDevice");
            binding.DeviceBindings["ExitGateReader"].RegexCollection.Add(
                                new Regex("exit*"));
            binding.DeviceBindings["ExitGateReader"].SourceBindingList.Add(
                                new SourceBinding("MySpecialDevice", "Antenna1"));

BindingManagerProxy bmp = new BindingManagerProxy();
bmp.SaveBinding(p.Name, binding);

Binding Event Handler Properties

Binding event handler properties is relatively much more straightforward than binding logical devices. You use the component name to identify your component and the BindingManager API to actually make the change:

ProcessBinding binding = new ProcessBinding();

//bind to the post to SQL component, set its database
//parameter to MyDatabase
binding.ComponentBindings["PostToSQL"] = new Dictionary<string, object>();
binding.ComponentBindings["PostToSQL"]
  [SqlServerSink.DatabaseParameterName] = "MyDatabase";

BindingManagerProxy bmp = new BindingManagerProxy();
bmp.SaveBinding(p.Name, binding);

You can update both device and component bindings at the same time. In fact, you must do this if you have components that have required parameter values. This is because BizTalk RFID validates component bindings every time you call the SaveBinding API, and rejects invalid/ incomplete bindings. This is great—errors that crop up during saving and deployment are more manageable, since the human who is performing the operation knows something is wrong and needs to be fixed.

ImageTip If you have an advanced scenario where you need to save invalid bindings (e.g., an intermediate save from a design tool), you can use the SaveBindingWithoutValidation method on the BindingManager API. In that case, you still have to fix up bindings and get them into a valid state before the process can be started.

If you are using source binding, ensure that the physical device has the sources with the names that you are interested in, and ensure that the tags are stamped with the correct source name. If the source name has changed or the tag is not stamped with the source name correctly, the tag will be rejected by BizTalk RFID even before it reaches your process.

Note to provider authors: if you are raising TagListEvents, all the events must be from the same source to ensure that source binding works correctly.

ImageTip The friendly name of the device is very important in ensuring that events from a device are routed correctly. Make sure that you can change the friendly name of the device only from BizTalk RFID. If you change the name directly from another management tool or API outside BizTalk RFID, the names could get out of sync, leading to errors when BizTalk RFID opens the device later.

Executing RFID Processes

To this point, you have seen how to create processes and bind them to devices. The next step is to actually start execution and process events. This is the step of bringing the model to life, so to speak. The good news is, for an RFID process, the model and the application are one and the same. You can deploy it and start it directly, and have a running application. In this section, you will see how that happens under the hood, what the runtime architecture looks like (see Figure 5-30), and what the artifacts created by the application are.

Image

Figure 5-30. The RFID process runtime architecture

RFID Process Runtime Architecture

The flow of events starts from the physical device layer and percolates through the provider into a component inside BizTalk RFID that you can best think of as a routing engine. The routing engine has two main functions: for a particular event type from a particular device and source, it determines the processes that are interested in the device. Note that there could be multiple processes interested in the same event. For each such process, there is a separate queue associated with it, called the event queue in Figure 5-30. The routing engine deposits the event in the queue and moves on to the next event. Thus, the queuing of events is completely decoupled from the actual processing of the event.

This store-and-forward capability is at the heart of the event processing runtime. Once an event is available in the queue to be processed, the event dispatch engine dispatches the event to an activated RFID process. The activated RFID process includes live instances of the event handler classes that are glued together by the runtime, so that events from the previous event handler are conveyed to the next appropriate event handler. During the processing of the event, if any of the intermediate event handlers returns a null value, the event is assumed to have been filtered and is rejected.

BizTalk RFID also creates a queue for holding the “rejects,” or events that could not be processed successfully. This is in keeping with the philosophy of at-most-once processing of events, and addresses scenarios where a single badly formed event could cause event processing to stall: the problem event is smartly moved to the suspended queue, and event processing continues as usual. BizTalk RFID has management APIs for retrieving and clearing the suspended queue.

Activation and Hosting

At process startup, the runtime creates singleton instances of all the event handler classes, and creates event routing paths for each event type. You can think of this routing path as the call-path in a C# program: the type of the event determines the exact methods that will be invoked and the sequence they will be invoked in. To guarantee process isolation, each RFID process is activated within its own .NET application domain. From an execution efficiency perspective, all the boxes on the right in the preceding runtime architecture diagram are activated in one application domain, and all the boxes on the left are activated in another application domain. There is no cross-application domain call for event processing, but events are transmitted through the event queue. This usage of application domains gives a certain amount of robustness and reliability to the runtime architecture.

After the process pipeline activation happens, the user code in the event handler class will be ready to consume events. BizTalk RFID schedules events as they become available, using the .NET thread pool. Multiple events can be concurrently processed at the same time, so if you have any state in your event handler classes, you must take care of the synchronization of access to such state. You should also not make any assumptions regarding the order in which events are processed. It is quite possible that events will be observed by the reader and delivered in one order, but consumed by the event handler in a different order.

If a process has a problem, the application domain can be torn down and a new one can be created without impacting other processes, up to a point. However, if they share the same Win32 process, there are certain operations where the activities of one process or provider will impact another, including but not limited to stack overflows, out-of-memory errors, memory leaks, and unmanaged access errors. This is where the hosting feature comes in. On Windows Server 2003 and Windows Server 2003 R2, BizTalk RFID hosts each RFID process and provider out of process from the BizTalk RFID server itself, using IIS as the application host.

BizTalk RFID Hosting Model for Windows Server

IIS 6.0, which ships with Windows Server 2003, has a lot of support for hosting applications. This includes the concept of an application pool, which determines the properties of the Win32 process used to host the application. Under Windows Server, each RFID process and provider gets its own web application and application pool. Other than that, all the aspects of the programming model remain exactly the same. You should think of the architecture from Figure 5-30 as having a Win32 process boundary at the queue layer. From a performance perspective, other than the overhead of having a few additional Win32 processes, you should not see significant deviations in the latency of event processing, since no new interprocess calls are introduced between the path where an event is raised and where it is consumed. The event consumption still goes directly through MSMQ, which is the same as in the nonhosted scenario. However, from a deployment and management perspective, the introduction of IIS is a significant moving part, and you should have a handle on the interprocess communication that is happening, which will let you interpret and troubleshoot issues. Figure 5-31 illustrates the process boundaries where interprocess communication through WCF is happening under the covers. Table 5-1 summarizes the differences between the two deployment platforms.

Image

Figure 5-31. BizTalk RFID hosting architecture on Windows Server 2003

Image

Transactionality

There are three supported modes for the “message handling reliability” of RFID processes. Basically, they govern the guarantees that BizTalk RFID gives to your application from a reliability perspective. As a colleague once told a room full of trainees, all those who want unreliable messaging, please put up your hand. Seriously, this mode essentially represents the trade-off between reliability and performance. Also, based on your scenario, you may not have any transactional component in your pipeline, in which case it would be unfair to impose the overhead of transactionality on your application. Here is a brief description of the knobs and how you might use them:

Transactional: This is the default level. For each event, the runtime creates a new transaction, which is available as the ambient transaction (Transaction.Current for those of you familiar with System.Transactions from .NET 2.0). Within this transaction, it dequeues a single event from the event queue. It invokes each event handler method within this same transaction. If the event handler writes the event to SQL Server, for example, it will enlist in this same ambient transaction by default. At the end of the event processing, the system will attempt to commit the global transaction. If the commit succeeds, all is well. If not, the system will roll back the current transaction, start a smaller transaction to dequeue from the event queue, and write the event to the suspended queue. The implications are that you get fully transactional, reliable event processing, which is great for enterprise applications. You also get clean, all-or-nothing semantics, where either the work done by all event handlers is committed, or the work done by none of them is committed. The downside is that you incur the overhead of a distributed transaction for each event that you process, and effectively, you are running at the speed at which synchronous writes can be made to the transactional logging subsystem. On most modern hardware, this means you can process a few hundred events per second, at best.

Reliable: In this mode, the queue is configured to use reliable storage. When an event is successfully posted to the queue, it guarantees that the event can be retrieved later. However, there is no explicit transaction created for each event. The queuing subsystem is free to optimize the batching of sends and receives as it feels appropriate from a performance perspective. If you have lots of concurrent activity, this is a great opportunity for the queuing subsystem to batch operations and attain significantly better throughput than transactional event processing. The runtime dequeues the event, and then executes it through the pipeline, without creating an ambient transaction. If you have an event handler that accesses a transactional resource such as a database, it will have to wrap the execution within its own transaction (SQL Server, for example, has an implicit statement-level transaction if you submit operations to it). In this model, if one event handler succeeds, but the other fails, the first event handler’s transaction commit will still stay and not roll back. You have more granular control over transactions, and you gain a significant advantage from a performance perspective. Typically, this kind of event processing yields three to four times the throughput of transactional processing, if the throughput was I/O-bound to start with.

Express: One of the developers who heard about this mode in the chalk talks called this “loosey-goosey event processing,” and the name stuck. With this mode, the event queue is configured to be “express”—the emphasis is on delivery speed and efficiency, not correctness. In this model, no guarantees are made that an event that was queued can be dequeued. Also, the runtime does not create an ambient transaction; it dequeues the event and has it processed immediately. In this mode of event processing, under some circumstances, the delivery of events from the provider to the event processing pipeline could all be accomplished without a single disk operation; hence, the throughput is significantly higher compared to transactional event processing. However, you get exactly what you paid for: occasionally, you may lose an event. If you can sleep easily at night knowing that most of your events will be processed very quickly, this is the right mode for you. Typically, it makes sense if your event processing is doing a lot of low-level filtering and elimination of duplicates: if you lose an event under such scenarios, it is usually not such a big deal, since the next one will be along a millisecond later.

Conclusion

This chapter covered the new asynchronous event processing model that is part of BizTalk RFID, which is at the heart of building RFID applications. Each asynchronous event processing application is implemented as an RFID business process. We stepped through the design, authoring, configuration, deployment, and execution of RFID business processes. We covered a lot of ground in this chapter, but in a sense, this new event processing model is really at the heart of what is new about BizTalk RFID.

CASE STUDY: TRACKING GUEST ACTIVITIES TO IMPROVE CUSTOMER SERVICE AND GUEST SATISFACTION

Industry: Tourism.

Overview: When boarding a tourist cruise ship, guests are given an RFID-enabled armband that they can wear throughout their stay. This armband provides access to all amenities, including their hotel room, the workout room, events, and access to the ship when at port. Additionally, the armband enables the guest to keep a running tab on purchases and debts, including trips to the bars, restaurants, casinos, and shows. At the end of the trip, their balance due is included on their final bill.

Results: The process not only improves the ease with which a guest can move around and make transactions during their stay, but it also improves customer service. When a guest steps out of their room, housekeeping can be notified, and the room can be cleaned. When a guest enters a casino, they can be greeted and served according to their needs. From a business perspective, tracking this information allows for extensive business intelligence based on the metrics that are created from numerous guest activities.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset