Inside Microsoft's component strategy
While much is made of HTML and pretty Web pages, the real power of the Web is the programmability of the server. Today, the combination of a browser and server-based Web applications are beginning to eclipse all other forms of client/server programming. The Common Gateway Interface (CGI), often derided as a 'hack,' has laid the seed for the Web to come alive. If HTTP allowed only static pages, the Web would not be the influence it is today. In recent months, the Active Server Page (ASP) architecture has emerged as an important method for delivering components in Microsoft environments.
There are many benefits to components: Reuse, ease of maintenance, and encapsulation of functionality. By using components, you separate form from function. You can achieve better scalability than with scripted solutions. Developers find too that there is a growing aftermarket for well-built, well-tested components. For developers in both Microsoft and "non-Microsoft" environments, components provide a faster route to project completion.
Early on, Microsoft realized the need to radically improve programmability of the server... Even in Version 1 of Internet Information Server (IIS), a Microsoft Web server product, there was a high-performance Application Programming Interface called ISAPI. ISAPI is often associated with Microsoft but in fact, it was developed by Process Software (insert location) and is used by a number of different Web servers. While ISAPI allowed high performance server-side applications, it was not easy for mere mortals to use.
Version 3 of IIS introduced Active Server Pages (ASP), which, too, are still understood by a relative few. In fact, ASP is a radical leap of power, programmability and extensibility that allows server-side applications to be written and maintained by a much broader base of programmers.
Active Server Pages, with a combination of server-side scripts, components and transacted-pages, is a very compelling and powerful environment for building Web applications. Active Server Components are key to Microsoft's efforts to promote re-use of functionality and allow scalability beyond scripting. In the wake of Active Server there has appeared a dynamic and growing third-party market for Active Server Components that provides "off-the-shelf" solutions for many common utility functions.
Key issues that confront Active Server development teams include threading strategy, transaction support, the importance of security, and choice of languages. As to languages, for many, the selection will be made between Visual Basic and Visual C++, but others are beginning to consider Java as an alternative. In any case, the context of ASP must be understood before successful projects can proceed.
Some ASP Basics
Each ASP page consists of standard HTML and server-side script. Server-side script is meant for interpretation and processing on the
server before transmission to the browser. The script can add or change the contents of the resultant page before the browser receives it. In fact, the browser is completely unaware that any server-side processing was performed. From the browser's perspective, the processed result is indistinguishable from a static Web page.
ASP is independent of the browser. In fact, a given ASP page can
determine the type of browser, and dynamically change the page view for optimal presentation on different browsers. The concept of server-side scripting is not unique to ASP. Netscape Communications, Mountain View, Calif., has Livewire, and several other vendors have specialized solutions using embedded tags. This make it very easy to iterate through designs.
ASP supplies six intrinsic objects that encapsulate many of the low level details that CGI and ISAPI programmers typically must deal with. The Request Object contains the browser's request, including parsed form and query string data and cookies. The Response Object contains everything to be returned to the browser: new HTML, HTTP headers, PICS (content rating) and the like. It is even possible to transfer binary data to and from the browser or a Java applet executing within the browser. The Session Object allows the ASP developer to maintain state across the page invocations of a particular user. The Application Object allows sharing of data across multiple users who are accessing a given virtual root. The Server Object gets and sets properties associated with the Web server itself, such as the amount of time a given script is allowed to execute before ASP will cancel it. Finally, IIS Version 4 includes Object Context for participation in page-level transactions.
For example, a given ASP page may create a transaction context whereby all participating components may commit or rollback all actions performed within the page. Transactions are typically
associated with database activity, and while database transactions can certainly participate, the innovation in this architecture comes from allowing any component to participate in the transaction. For example, a given page may log an action in a database as well as send a message via Microsoft Message Queue. If the database write fails for some reason, then the entire transaction will be rolled back and the message will not be sent.
ASP permits the notion of Server-side components or Active Server Components (ASC). Active Server Components permit the encapsulation of functionality into a packaged, binary, re-usable object. ASP's use of Server-side components is its most powerful feature. ASC's and IIS extend Microsoft's COM architecture for use by developers of Web applications.
ASC's can be re-used in multiple applications or in multiple modules of the same application. If server-side scripting were used exclusively, there would quickly be a code maintenance nightmare as snippets of script are cut and pasted between ASP pages. When a script is executed, the results are sent to the browser and execution completes. There is no way by scripting alone to create service processes or worker threads.
A component has considerable flexibility to process functions even when a page is not being executed. It is possible for a component, coupled with an NT service, to perform tasks in the background. This means quicker response to user request and greater potential scalability of the Web application. More sophisticated components can be designed to off-load processing to other servers rather than burdening the Web server. A description of component varieties follows.
Line of Business Components. Such components contain the essential functionality of a Web application. Typical examples include shopping carts, order processing, insurance policy processing. A well-designed Line of Business component does not have any user interface functions -- it only encapsulates business rules and functions.
Utility Components. These components are used to access WIN32 or other functions from within a script or another component. Typical examples include sending e-mail, accessing files, reading or writing the system registry, or logging critical events to the Event Log. Utility components are highly re-useable between applications. This is also where the greatest variety of third-party components exist.
Data Components. Unlike business components which implement business rules, Data Components are useful to share data between multiple clients. Clients are not necessarily all Web-based. A Data Component might be re-useable both with an ASP page as well as within a classic client/server Visual Basic application.
Presentation Components. Presentation Components interact with the user, typically by internally using the ASP intrinsic Request and Response objects. Note that, unlike the other categories, Presentation Components are specific to ASP and cannot be re-used in other environments. For example, a component that took as input a result set from another component and displayed it using a specific HTML table definition would be a Presentation Component. By re-using this same component in multiple applications, there would be a consistent look and feel to the applications. Another example would be a graphics server that would dynamically generate JPEG files for display on the browser.
A component must support Automation (formerly known as OLE Automation) in order to be invoked from an ASP script. Automation is the key technique that allows a script to bind to specific functions of the component at run-time and share variables of differing types. If a component does not support Automation, it cannot be used directly from ASP script. However, it is still possible for another component to use the non-Automation interfaces.
Since the component is running in the context of the Web server, performance is critical. Virtually all ASC's are 'in-proc,' which means that they execute within the same process as IIS, and are packaged as DLL files rather than EXE files. In-proc execution can improve overhead for method invocations by as much as one-thousand fold! Any ASC can access all of the same intrinsic objects that ASP makes available to the script: Request, Response, Session, Application, Server and ObjectContext. However, by using the intrinsic objects, the ASC can only be used within ASP. It cannot be used with Visual Basic or any other environment. It is possible to design components that can be used within both ASP and non-ASP environments. Indeed, most Line of Business components should be designed this way. Clearly, accessing the ASP intrinsic objects should be confined to Presentation Components. A component can also decide appropriate behavior at run-time, and if the ASP intrinsic objects are not available, the component can function in a degraded state rather than aborting. Finally, an ASC can elect to participate in transacted Web pages. The ASC then gets a chance to vote whether a given transaction should be committed and allowed to complete successfully, or should be aborted and completely rolled-back.
Microsoft has spent a lot of time optimizing IIS for large server loads in production environments. This has a downstream effect of placing new burdens on the component developer that do not exist in the simple world of single-threaded, classic GUI environments. In fact, many existing third-party ActiveX controls, components and libraries were not designed to work in the demanding multi-threaded environment of the Web server. The component may still function, but if it does not correctly support the IIS threading models, overall Web server performance could be significantly compromised.
When development teams truly learns the IIS/ASP environment they are forced to examine and understand threading and security issues that are often neglected in non-ASP components. Adding supports for these items later on can be much more expensive.
ASCs have no graphical user interface. This means that it is not appropriate, and usually not even possible to display a message box when an error has occurred. It also means that there is no Windows message queue. Any user interaction must be performed using the Request and Response objects.
For performance reasons, IIS/ASP extends COM's threading model. The IIS threading model has a significant impact on performance of the Web server, the security context of the component and the component's ability to support transactions. There are some points to keep in mind when pursuing IIS threading. COM defines four threading models:
- Free, and
If an ASP page is invoking a component that is in a different threading context than the page, COM will have to intervene in order to resolve this difference. When COM intervenes, it is called marshalling, whereby COM packages the method invocation such that it is possible to cross boundaries. (QA?alteration okay?) Marshalling is an expensive operation and is to be avoided in the case of an ASC.
Single refers to main line of execution of a process. Every process has at least one thread. Components that use the Single threading model will only execute on the main thread of the process. This means that all execution within the component will be sequential. If there are multiple single threaded components on a particular Web server, then all of these components will execute sequentially, even if they exist in different Web applications. One user calling up an ASP page that uses single threaded components can block many other concurrent users. Except for the most simple of Web sites, this creates an unacceptable performance bottleneck. No ASC should ever use the single threading model.
Apartment allows multiple threads, but execution within a specific instance of a component is sequential. Let's say a user calls up a specific ASP page that creates an ASC. All of the methods calls (QA? alteration okay?) to that ASC on that page will be sequential. If, at the same time, another user calls up the same page, a second instance of the component will be created. The two different instances can execute in parallel on separate threads. COM will guarantee that method calls are sequential within a specific instance, and allow multiple instances in different threads.
The Apartment model is an example where IIS extends the COM threading model. COM's formal rules specify that if a component uses the Apartment model, the component will be created on a single thread, have all method calls on that same thread, and terminate on that same thread. If IIS were to implement this, it would have to maintain hundreds of threads on a moderately loaded server. Instead, IIS uses a thread pool. For the component, there are important ramifications. It means that the component is no longer guaranteed to be created on the same thread where method invocations will occur. This restricts options available to the component: it cannot use thread-local storage, and it cannot create other components in a different apartment using standard COM API calls. Creating components in a different apartment means that COM will create a proxy to marshal calls across apartment boundaries. This proxy exists in thread-local storage which may disappear between method calls, causing calls to the sub-component to fail. Instead, ASP provides a helper method in the Server object to create sub-components which avoids this problem.
Free threading allow a component to receive method calls concurrently from many threads. All synchronization must be handled internally to the component.
"Both" is a name describing a component that supports both the apartment and free threading models and is equally adept in either context. This is the preferred model for use within ASP since it avoids marshalling in all possible ASP contexts.
ASC can be written in any language that supports COM and Automation. This includes common Microsoft languages such as Visual Basic, Visual C++, Visual J++ as well as many others.
Visual Basic is a popular language for development of line of business applications. VB Version 5.0 components are single-threaded by default. Starting with Visual Studio Service Pack 2, Visual Basic has been updated to allow creation of components that are apartment-model. Any ASC developed used Visual Basic should ensure that the apartment model is enabled.
Visual C++ can create high performance components that use any threading model. It also offers the greatest flexibility in accessing system services and APIs. Visual C++ is the language of choice for ultimate performance and flexibility at the expense of highest development cost.
Java, or more specifically the Visual J++ variant, can create high performance components that use any threading model. It is not as flexible as C++ in accessing system services and APIs, but can be easier to use, especially with regards to pointer manipulation. Starting with IIS 4, there are a series of helper Java classes to ease the burden of development, and most of the sample ASC supplied by Microsoft are written in Java. There is also a third-party tool that allows execution of standard Java servlets as ASCs.
As useful rules of thumb: For most rapid development time, use Visual Basic; for highest performance and flexibility use Visual C++; for the best overall compromise, assuming the development group is not already strongly committed to Visual Basic or C++, use Visual J++.
In conclusion, Active Server Component will help deliver COM concepts to a wider audience. Developers in this audience will reach their own conclusions regarding which threading methods and languages best meet their needs. And, as components become more familiar, developers will enjoy more options. By defining a binary standard for components, Microsoft has let blossom an after-market for hundreds of third-party components. No other web server has such an extensive collection of ready to use components from Independent Software Vendors.