Managing State in a Web Application

[Previous] [Next]

Why does state management pose so many problems in a Web application? For the most part, it's because HTTP is largely a connectionless and stateless protocol. The lightweight nature of the HTTP protocol assumes that the Web server forgets all about the client the instant it's done processing a request. In contrast, DCOM and RPC provide a very connection-oriented protocol that makes it easy to maintain client-specific state on the server computer.

Many Web developers store HTTP cookies on the client computer to manage client-specific state across a series of requests. Your server-side software can generate a cookie to track each client session. You must write application logic to send cookies back and forth in requests and responses. In some applications, the developer must generate and transmit a cookie at the beginning of every session as well as look for cookies in each incoming request to identify a particular client.

As you know, the ASP framework provides state management features through two built-in ASP objects. The Session object is a name/value dictionary that provides a simple way to track client-specific state. The ASP framework provides the convenience of managing a cookie for each client session behind the scenes. The Application object is a name/value dictionary that allows you to store state that's available to any request running in the same IIS application.

I'll assume that you know how to read and write to ASP Session and Application variables from an ASP page. You should also know that it's possible to access ASP Session variables and ASP Application variables from a Visual Basic component. To refresh your memory, let me reiterate an important rule I covered earlier in this chapter: Never store a Visual Basic object in an ASP Session variable or an ASP Application variable.

Using all this knowledge, you often must decide how to maintain client-specific state across multiple requests. For instance, if you're designing a Web-based shopping cart application, you must build a session-based state machine that allows a client to select products and enter payment information across a series of requests.

The first question you must answer in the design phase is whether it's acceptable to store client-specific state on the Web server computer. You can't do this in some scenarios—such as when you're writing ASP pages and Visual Basic components for a Web farm environment. Storing client-specific state on a Web server only works if all the requests from a single client are routed across the same IIS computer, and many load balancing schemes used by Web farms do not impose such a restriction. Complicated environments such as Web farms typically require stateless techniques in which client-specific state is stored in a backend database or sent back and stored on the client using something like cookies or invisible HTML controls.

I'll defer the discussion of problems posed by a Web farm environment until later in this chapter. For now, we'll look at a simpler scenario. If you can make the assumption that you're writing ASP pages and Visual Basic components for a Web site based on a single IIS computer, you can use ASP Session variables to manage client-specific state.

When you use ASP Session variables to hold your state across requests, you should store simple values (primitive data types) instead of Visual Basic objects. When you store your state in ASP Session variables using data types such as Integer, Double, and String, IIS can process future requests using any available STA worker thread from the pool. When you use this approach, you can even use ASP Session variables to hold complicated data structures such as arrays and Variants.

Let's look at an example that uses a Visual Basic object to read and write state to and from an ASP Session variable. You can use the following code to write a simple string value to an ASP Session variable named MyState:

 Dim sess As Session Set sess = GetObjectContext("Session") sess("MyState") = "Some data related to this client" 

In a future request for the same client, you can retrieve the state from the same ASP Session variable as follows:

 Dim sess As Session, s As String Set sess = GetObjectContext("Session") s = sess("MyState") 

For a slightly more complicated example, let's say you need to store a set of line items for a client's shopping cart. You can accomplish this by storing a string array in an ASP Session variable, as shown here:

 Dim sess As Session, LineItems() As String Set sess = GetObjectContext("Session") Redim LineItems(1 To 3) LineItems(1) = "Product=Dog;Quantity=5" LineItems(2) = "Product=Cat;Quantity=10" LineItems(3) = "Product=Bird;Quantity=25" sess("ShoppingCart") = LineItems 

A future request can append additional line items to the array or run a transaction to purchase the items. Using ASP Session variables in this manner allows you to build stateful applications and sites that use a shopping cart metaphor (like Amazon.com).

The one key aspect of designing an application that uses ASP Session variables is that you must make an assumption about how your application will be deployed. Each client must be guaranteed that its requests will be serviced by the same IIS computer. In the next section, we'll look at some factors that might make it impossible for you to make this assumption.

Scaling a Web Application Through Load Balancing

A Web site is like an aspiring Hollywood actor. At the beginning of its career, its biggest problem is paranoia about forever living in obscurity. When it becomes famous, it has a new set of challenges. The volume of incoming requests increases dramatically and its fans have lofty expectations about the site's performance and are highly critical when these expectations are not met. Unfortunately, these challenges are sometimes more than a Web site can handle. Some Web sites respond to fame by going up in smoke, and they never recover. The Web sites that can handle the pressure more gracefully go on to become the places that thousands of users return to again and again.

Some Web sites (often the children of famous Web sites) are famous from the day they're launched. Others see their user base grow from hundreds to thousands to hundreds of thousands of users on their path to fame. To meet the demands and the expectations of their fans, these sites must scale accordingly.

I touched on the concept of scalability in earlier chapters, but it's important to look at it one more time. A simple definition of scalability is a system's ability to accommodate a growing number of clients and to give each client satisfactory levels of responsiveness. To reach this goal, a Web site must supply an adequate number of processing cycles per second to handle the volume of incoming requests. As you might expect, more clients require more processing cycles. So the question becomes, "Where do all these processing cycles come from?"

At first, you might be able to increase your site's scalability with a single-server solution. You can upgrade your Web server to a computer with a faster processor or multiple processors or both. This is what's known as scaling up. For example, you can buy a Web server with two or four really fast processors. The new computer will handle a larger client base than the previous computer. However, at some point a single server solution simply won't cut it. You can only scale up so far. Moreover, the computers at the high end of that market are prohibitively expensive. Once you hit a certain threshold, cost-effective scalability requires the use of multiple processors spread across multiple computers. You often hear people say that you need to scale out rather than scale up.

This is where load balancing comes into play. You have to distribute the workload of incoming HTTP requests across several not-so-expensive computers. We'll look at several approaches to meeting this challenge. For a Web-based application, it's better to address load balancing at the point where the HTTP request arrives at the site. This means you need a technique to distribute incoming HTTP requests across a set of IIS computers. A site that uses this approach is often called a Web farm or a Web server array.

Creating a web farm

Web designers have quite a few techniques for distributing HTTP requests across a set of servers. One simple approach is to design a Web site with a dedicated routing server that has custom code to redirect clients, as shown in Figure 9-8.

click to view at full size.

Figure 9-8 You can build a session-based Web farm by using a routing server to distribute a set of clients across a set of IIS server computers.

The routing server is given a well-known DNS name (such as MySite.com) and a dedicated IP address. Other servers in the farm have their own dedicated IP addresses and optionally DNS names. When a client's initial request reaches the routing server, the request is redirected to one of the other servers in the farm. You can redirect clients from the routing server using the Session_OnStart event in the global.asa file. The code in Listing 9-2 shows one possible implementation.

Listing 9-2

 Sub Session_OnStart Const SERVER_COUNT = 3 Dim sServer, sURL Randomize Select Case (Fix(Rnd * SERVER_COUNT) + 1) Case 1 sServer = "FarmWorker1" Case 2 sServer = "FarmWorker2" Case 3 sServer = "FarmWorker3" End Select sURL = "http://" & sServer & ".MySite.com/MyApp/default.asp" Response.Redirect sURL End Sub 

This technique requires that the client's initial request to the routing server be for a page with an .ASP extension. The Session_OnStart event won't fire if the request is for a file with an .HTM or .HTML extension. The algorithm shown above redirects each new client to one of three servers in the farm. Once a client is redirected to an IIS computer in the farm, a session is created and the client sends all future requests to the same address. For this reason, you can think of this as a session-based load-balancing technique.

The algorithm I just showed you uses a random number for redirection, but you can design a more elaborate load-balancing mechanism. For instance, each server in the farm can send performance data back to the routing server. If each server periodically transmits a count of active sessions to the routing server, the load-balancing code can redirect each new client to the server with the fewest active clients.

Round-robin DNS is another common session-based load-balancing technique. With round-robin DNS, each logical DNS name (such as MySite.com) maps to several IP addresses. When a browser attempts to resolve the DNS name, the DNS server sends back one of the addresses from the list. The DNS server rotates the addresses in order to distribute a set of clients across a set of servers. Once a browser resolves a DNS name into an IP address, it caches the IP address for the duration of the client's session. Round-robin DNS is slightly faster than the redirection technique shown above but produces the same results. Different clients are given different IP address to balance the load across a set of servers.

To set up a Web farm with one of these session-based load-balancing techniques, you should use relative URLs in your ASP pages and Visual Basic code. For instance, you should use a URL such as /MyOtherPage.asp instead of an absolute URL that contains a server's DNS name or IP address. This will ensure that each client continues to send requests to the same server once a session has started.

While both of these forms of session-based load balancing are fairly easy to set up, they have a few notable limitations. First, load balancing is performed only once for each client at the beginning of a session. The load-balancing scheme can get a little skewed. For instance, all the users who've been sent to FarmWorker1 might go to lunch while all the users who've been sent to FarmWorker2 continue to send requests. In this case, one server can get overloaded while another server sits idle.

A more significant problem has to do with a Web application's availability. Session-based load balancing exposes the IP addresses of the servers in the farm to the client. This is limiting because each IIS computer becomes a single point of failure.

What happens when one of the Web servers in the farm crashes or is taken off line for maintenance? The load-balancing algorithm must take this into account as soon as possible, but this can be problematic. If the routing server or the DNS server passes out an IP address for a server that's gone off line, clients receive a "Server not available" error. With some round-robin DNS systems, it can take you a long time to fix the problem once you've discovered that one of your servers has crashed. Things can get really bad if IP address mappings need to be propagated to other DNS servers throughout the Internet.

To make things worse, when a Web server goes off line, it affects every client for which it was holding session-specific state. In other words, when the Web server crashes, client sessions can crash along with it. As you can see, the load-balancing techniques you've seen so far can compromise the availability and fault tolerance of a Web application. Fortunately, you can use more sophisticated approaches to load balancing that sidestep these problems. The solution lies in exposing a single IP address to every client.

Designing a better Web farm

As you've seen, exposing multiple IP addresses for a single Web site can compromise availability and load distribution. It's better to expose a single IP address that maps to several physical servers. However, this solution requires low-level networking code to reroute incoming IP packets across a set of servers. Most companies opt for an off-the-shelf solution rather than rolling their own. We'll take a look at some of the more popular options in this section.

First, we'll look at how you can perform load balancing with a hardware-based product such as the LocalDirector switch from Cisco or the BigIP router from F5. Then we'll look at Network Load Balancing (NLB), a software-based solution included with Windows 2000 Advanced Server. You should note that many other vendors offer similar products. This market is quite competitive, so you should conduct your own research to determine who can offer you the best combination of price and performance.

Figure 9-9 shows the basic configuration of a site with a hardware-based solution. A router or switch listens for incoming requests on a single virtual IP address and can reroute them across a set of IIS server computers. Each computer in the farm has its own unique IP address. However, unlike the load-balancing techniques we discussed earlier, the IP addresses of the physical servers are never seen by clients. Load balancing is performed every time a request comes in across the "virtual" IP address. This approach is known as request-based load balancing.

click to view at full size.

Figure 9-9 A hardware-based solution can provide request-based load balancing. Client requests are made to a single virtual IP address and are rerouted across a set of physical IP addresses.

NLB is a Windows service that represents a software-based solution for achieving request-based load balancing. NLB can be used by many types of applications that rely on IP traffic. In the rest of this chapter, we'll focus on using NLB to create a Web farm.

The NLB service is based on Convoy Cluster software purchased by Microsoft from Valence Research. Unlike LocalDirector or BigIP, NLB doesn't require a proprietary piece of hardware. It's installed as a Windows device driver on each machine in the farm, as shown in Figure 9-10. NLB can accommodate a Web farm of up to 32 servers.

click to view at full size.

Figure 9-10 Network Load Balancing allows a set of computers running Windows 2000 Advanced Server to monitor a single IP address.

When you set up a Web farm using NLB, all the servers are in constant communication with each other. They exchange performance statistics and divide up the responsibilities of handling incoming requests. Every incoming request is seen by every server in the farm, and the NLB service has a proprietary algorithm to determine which server handles each request.

NLB has a few advantages over a hardware-based solution. It doesn't require a proprietary hardware device, and there isn't a singe point of failure. If you're going to use a hardware-based solution, you can usually buy a second failover device to improve availability and fault tolerance. Some companies find that a hardware-based solution with failover is too expensive for their needs. However, the argument for a hardware-based solution is that it has a one-time cost. With a software-based solution, you usually have to pay additional licensing fees every time you add another server to your Web farm. Once again, I'll leave it to you to do the research into which solution is best for your application.

LocalDirector, BigIP, and NLB differ significantly in their low-level plumbing details. But from a high-level perspective, they produce the same results. Each client makes a request using a virtual IP address, and the request is routed to one of many IIS server computers in the Web farm. Request-based load balancing has many advantages over session-based load balancing. Request-based load balancing is more granular because the load-balancing algorithm is run far more frequently. This results in a more even distribution of requests across servers.

The primary motivation for using request-based load balancing is to achieve higher levels of availability and fault tolerance. Both NLB and hardware-based solutions can detect when a server has gone off line and can quickly recover to avoid routing future requests to an unavailable IP address. Moreover, an administrator can safely take a server off line during operational hours. For example, the administrator can perform a rolling upgrade, which involves taking Web farm computers off line one by one. Rolling upgrades make it possible to do things such as shut down INETINFO.EXE in order to revise a set of Visual Basic DLLs. The idea behind a rolling upgrade is that the Web site as a whole never experiences an interruption in service.

Request-based load balancing also has disadvantages. One of the main disadvantages is that managing state in a Web farm becomes more complicated because you can't assume that a client's requests will be serviced by the same IIS computer. If you can't make this assumption, you shouldn't attempt to maintain state using ASP Session variables. You must design a more sophisticated approach to session management. There are also several important issues concerning the use of ASP Application variables in an environment that uses request-based load balancing.

Maintaining state in a Web farm

If users of your Web application will simply be browsing for information, you don't have as many concerns about maintaining state. However, if your Web application involves something like a shopping cart, you must carefully consider how to build up and store state for each client across requests.

You should start the design phase by asking yourself a simple question: Where can you maintain client-specific state in your application? You have three choices. First, you can store state on the client computer using cookies or store state in the HTML that you send to the browser. Second, you can store state in the middle tier in IIS. Third, you can store state in a back-end DBMS such as SQL Server.

When you design a Web application for a site based on a single IIS computer, storing state in IIS using ASP Session variables is usually the easiest and most straightforward approach. If you have a Web farm that uses session-based load balancing, you can also store client-specific state in IIS. However, if you have a Web farm that uses request-based load balancing, most techniques for storing data in IIS don't work correctly.

If you can't store state in IIS, you must resort to one or both of the other options. The main advantage of storing state on the client is that it can be done quickly. You don't need to make time-consuming trips to the back-end database. Some of the advantages of storing state in the back-end database are that the data is durable and you can store as much state as you need. Storing state on the client has size limitations and also raises security issues. Many companies don't want to store sensitive information on the client's computer. Moreover, some client-side security settings can prevent you from writing to the client's hard disk.

You should note that when you store state in a back-end database, you'll probably still be required to maintain a minimal amount of state on the client. For example, it's common to explicitly pass a customer ID or some other type of primary key between the client and IIS with every request so that you can map a user to one or more records in your database. Sometimes you can get away with using something that HTTP sends anyway, such as the client's IP address or user name. As you can see, it's possible to maintain a little client-side state but still keep the majority of your data in a database such as SQL Server, where it's safe and secure.

During the design phase, you should also consider the following questions when you're deciding whether to write your client-specific state to a back-end database. How will accessing the back-end database affect performance? Will the back-end database be a significant performance bottleneck? If so, you might consider eliminating or reducing trips to the back end. You should do some benchmarking and compare the response times of requests that involve database access against the times of requests that do not.

You can usually reduce the number of trips to the database but not avoid them completely. Here are a few more questions you should consider during the design phase. How costly will it be to you if client-specific state gets lost or corrupted? Do you want the same client-specific state to be available when a user moves to a different machine? Is your client-specific state so sensitive that you need to hide it from your users? Do you need to store so much client-specific state that it's not practical to store it all on the client?

You can usually find a suitable compromise in terms of how much to write to your database. For example, you might access the database on the client's initial request to validate a user name and password and to retrieve a set of preconfigured user preferences. Then, as the user starts adding items to a shopping cart, you can track those actions by storing state on the client computer. Finally, when the user purchases the items, your application can make a second trip to the database to record the transaction. In this scenario, the client's session might involve 20 to 30 requests, but only 2 will require a trip to the back-end database.

Passing state between IIS and the browser

Whether you're maintaining lots of client-specific state on the client or just a primary key, you need to know how to pass data back and forth between the browser and IIS. In this section, we'll look at three common techniques for doing this.

The easiest way to store state on the client is by using HTTP cookies. The ASP Response and Request objects make writing and retrieving a cookie value relatively simple. For instance, you can write a cookie into an HTTP response like this:

 Dim rsp As Response Set rsp = GetObjectContext.Item("Response") rsp.Cookies("UserID") = "BrianR" rsp.Cookies("UserName") = "Brian Randell" rsp.Cookies("FavoriteFood") = "CheeseBurger" rsp.Cookies("FavoriteQuantity") = "3" 

If you write cookie values in an HTTP response, they'll flow back and forth with each request-response pair. Cookies are just as easy to read using the ASP Request object. The cookies in the example above live for the duration of the browser's session.

You can also store persistent cookie values on a user's hard drive. If you do this, these cookie values will live across sessions of the browser. This means that your site can remember all sorts of information and maintain user-specific preferences across visits. Users seem to appreciate sites that do this. To store a persistent cookie value to your user's hard drive, you simply add an expiration date as follows:

 rsp.Cookies("UserID") = "BrianR" rsp.Cookies("UserID").Expires = "July 1, 2001" 

In a shopping cart application, you can use cookies to build up a complex data structure across successive hits. Here's an example of writing multiple values to a single cookie to store line items for a shopping cart:

 rsp.Cookies("LineItemCount")= "3" rsp.Cookies("LineItems")("Item1") = "Product=Dog;Quantity=5" rsp.Cookies("LineItems")("Item2") = "Product=Cat;Quantity=10" rsp.Cookies("LineItems")("Item3") = "Product=Bird;Quantity=25" 

You should note a few important limitations of using HTTP cookies. First, they don't work across domains. Second, there's a limit on what you can store in a cookie. Most browsers support cookies of up to 4096 bytes. While you can write multiple cookies to one client, larger sets of data can become impractical to work with. Third, you can't assume that all clients support cookies. Some browser are simply too old to support them. Furthermore, some users disable cookies in their browsers after reading warnings from conspiracy theorists.

If you have to support clients that don't support cookies, you can't store data that will live on the client across sessions of the browser. You must also come up with a different technique to pass client-specific state back and forth. One popular technique involves using query strings to append named values to your URLs. For instance, instead of setting your HTML form's action to \MyPage.asp, you can append a query string to the URL like this: \MyPage.asp?UserID=BrianR.

Appending named values to URLs requires additional effort on your part. You must dynamically embed these name/value pairs to the end of every URL when you generate the HTML for your pages. Also, you're generally limited to about 2 KB when you manage state with query strings.

You should have one last client-side state management technique up your sleeve. This technique involves using a hidden field in an HTML form. If a user won't accept cookies and you want to store more state than you can append to a URL in a query string, this might be the solution you're looking for. Note that this technique requires the use of an HTML form and a Submit button. Here's an example of what your form might look like:

 <FORM ACTION="MyPage.asp" METHOD="Post"> <INPUT TYPE="Hidden" NAME="UserID" VALUE="BrianR"> <INPUT TYPE="Submit" VALUE="Get Past Purchases"> </FORM> 

A few more words on optimization

Products such as the NLB, LocalDirector, and BigIP allow you to turn off request-based load balancing and resort to session-based load balancing (also known as sticky sessions). For example, if you adjust the Affinity setting in NLB, you can tell the service to route each client to the same physical server once the first request goes through. This might be good news if you have a large, preexisting Web application that has dependencies on ASP Session variables.

The bad news is that resorting back to session-based load balancing compromises an application's performance and availability. You lose out on many of the benefits provided by request-based load balancing. It slows things down because the routing mechanism has to maintain client-to-server IP address mappings and perform a lookup for each request. It also makes your site vulnerable to problems with fault tolerance and distribution skew that we discussed earlier. What's more, additional problems arise when client requests are routed through a proxy server.

For example, it's possible for hundreds or thousands of clients to be associated with a single proxy server. This means that your load-balancing mechanism might see a large set of clients as a single IP address. You might have a situation in which 3000 users who share the same proxy server are beating the stuffing out of one of your Web servers while nine other servers in the farm are sitting around with nothing to do.

To make things even worse, America Online (AOL) has a proxy farm that's so big that it spans multiple class C addresses. However, a class C address is the coarsest level at which affinity works in NLB. This means that the requests of one AOL user are often routed across multiple NLB computers even when affinity has been turned on. In such a case, Session variables cause problems even when you're using sticky sessions.

My point is that if you can use request-based load balancing, you should resist going back to session-based load balancing, which is kind of like buying a Porsche and driving 30 miles an hour on the freeway. You should realize that all the "session-aware" features primarily support applications that have dependencies on middle-tier state. Your Web application will scale much better if you don't introduce these dependencies into your design.

Now, let's say you've been very disciplined throughout the design phase and you've created a Web application that has no dependencies on ASP session management. At this point, you can and should perform one more optimization: You should disable session management. As it turns out, IIS conducts a lot of session management work on your behalf unless you explicitly disable the session management feature. Leaving this feature enabled can unnecessarily waste precious resources such as processing cycles, memory, and network bandwidth.

So, what happens if you don't disable ASP session management? When a client requests an ASP page, the ASP framework checks to see whether the client is associated with an active session. If it's the client's first request, the ASP framework carries out a bunch of tasks to start tracking the client's session. ASP generates a unique SessionID and starts passing it back and forth in HTTP cookies. ASP also searches for the Session_OnStart event and executes it if it exists. If the ASP framework finds a valid SessionID in an incoming request and determines that the user is part of an active session, it must map the current request to any client-specific state that might have been stored in ASP Session variables in earlier requests.

The ASP framework also performs extra work to serialize all requests for any one session. This support eliminates concurrency problems relating to session state. However, this serialization of requests from any specific client is also costly and restrictive when it's not necessary. For example, let's say that your application defines two frames in the browser and each frame is based on an ASP page. One ASP page has to be completely processed before the ASP runtime begins processing the second one. If session management has been disabled, IIS can process both ASP pages at the same time on two different threads. This issue becomes especially important when the Web server computer has multiple processors.

As you can see, the ASP session management features are expensive. If you don't need them, you should turn them off by clearing the Enable Session State check box in the Internet Services Manager. You can turn off session management for an IIS application or for the entire site. You can also turn off session management by placing the following declaration at the top of all your ASP pages:

 <%@ EnableSessionState=False %> 

Caching Application-Wide State

The final topic I want to discuss in this chapter is how to manage application-wide state in a Web site. The ASP framework provides the Application object for sharing a single set of variables across a set of clients. Each ASP application variable is accessible to every request in a given IIS application.

Using ASP Application variables is similar to using the Shared Property Manager (SPM). It simply provides a way to cache data in memory within a process and share it across a set of clients. In fact, in many situations you can use ASP Application variables and the SPM interchangeably. Let me list the advantages of each approach.

If you'll be caching updateable data, the SPM can provide more granular locking because you can partition your cached data into several property groups. The locking scheme used by the ASP Application object allows for only a single course-grained lock. Another potential benefit of the SPM is that it doesn't have a dependency on the ASP runtime. You can use the SPM to create a configured component that provides a caching scheme and then use the component in a COM+ application with both Web-based and DCOM-based clients.

Many ASP developers find that ASP Application variables are easier to use. These variables are also accessible directly from an ASP page, while the SPM is not. The ASP Application object also makes it easier to release memory that's no longer needed. The ASP Application object and the ASP Session object both provide a Contents property that exposes a Remove method and a RemoveAll method. The SPM doesn't provide similar functionality.

Whether you use the ASP Application object or the SPM to track application-wide data, you must decide during the initial design phase whether the code you write will run in a Web farm environment. When clients are routed across a set of IIS server computers, it's difficult to cache updateable data. You often have to make the assumption that cached data, once loaded from a database, will be used on a read-only basis.

Caching read-only data at the Web server is one of the best ways to improve response times and increase overall throughput. Caching techniques are valuable because they reduce the required number of round trips to the database. They can also conserve server-side processing cycles. For example, after retrieving the products table in an ADO recordset, you can format the data into an HTML table or into XML and cache it as a string value in an ASP Application variable. This technique reduces the need to convert data on a request-by-request basis.

If you're going to design a middle-tier caching scheme for read-only data, you should also make assumptions about how long your data will stay fresh. In some cases, you can load data into ASP Application variables once at application startup or whenever the data is first accessed. In other applications, you might decide to have data refreshed at periodic intervals.

Here's an example to illustrate what you can do to design a caching coherency scheme. Let's say that you want to cache an HTML table for the product list in an Application variable, and you assume that product data will change often enough that the HTML table should be refreshed every five minutes.

In your design, you create one ASP Application variable to hold the actual product list and another Application variable to track when the list was last refreshed from the database. Any ASP page or Visual Basic component can examine the time of the last refresh when retrieving the list. When the code running in a request determines that the interval between the current time and last-refreshed time is greater than the refresh interval, it can requery the database and regenerate the list for itself and any other request issued in the next five minutes. If you're a forward-thinking COM+ designer, you can also keep the refresh interval in a configured component's constructor string so that you can easily adjust it without recompiling any code.

Summary

This chapter has covered some of the important issues relating to building large-scale applications with Visual Basic. Applications that use HTTP for client-to-server communication are far more scalable than applications that rely on DCOM and RPC. The Web and HTTP also open up a whole world of cross-platform development.

If you're designing and building Web sites with Windows 2000 Server, you must understand the architecture of IIS and ASP. These core technologies allow you to expose ASP pages and Visual Basic components to clients across the Internet as well as the corporate intranet, not to mention business-to-business extranets. As you've seen, many subtle aspects of the technology affect how you write your ASP pages and Visual Basic components. Unfortunately, many programming techniques and deployment schemes prevent an application from scaling to meet requirements for response times and overall throughput.

What I hope you take away from this chapter is that you must think long and hard about scalability early in the design phase. Many designers and developers who didn't design with scalability in mind now deeply regret the dependencies their applications have on ASP Session variables. Their applications will probably never make it in the big leagues.

It's often impossible to anticipate how busy and successful your site will become. If you know that your site will never get more than a few requests per minute, you don't have to worry about many of the details I covered in this chapter. But if you're not sure, you shouldn't take any chances. When you begin designing a Web application, start with the assumption that it might one day be the most popular site on the Internet.



Programming Distributed Applications with COM+ and Microsoft Visual Basic 6.0
Programming Distributed Applications with Com and Microsoft Visual Basic 6.0 (Programming/Visual Basic)
ISBN: 1572319615
EAN: 2147483647
Year: 2000
Pages: 70
Authors: Ted Pattison

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net