Connection Flyweight

[ComponentDesignPatterns | CategoryPattern]

Problem

Forces

Solution


Intent

Allow multiple independent entities to use external connections without always incurring the overhead of connection creation.

Also Known As

Connection Pool, Connection Cache

Motivation

In a component-based application, particularly those that either use the web, or have a large number of "thin" clients, the overhead required to create and obtain a connection to an external resource (e.g. database, CORBA server, etc.) is often more costly than the rest of the application. For instance, if we consider a web-based online-purchasing system (like Amazon.com) there may be thousands of users querying the database for book information each minute. In a traditional client-server environment, each client would:

In most systems, the first step takes the longest. If obtaining a connection takes even a small fraction (say 25%) of the total time to run the transaction, then a major speed increase can be gained by omitting that step. Therefore, many programmers have taken the following steps: Before creating a new connection, look in a connection pool to determine if there is an existing, but unused connection that will meet their needs. Only in the case where no connection is available will another one be created. This application of the FlyweightPattern is simple, but can provide significant benefits.

Related Patterns

ConnectionSingleton

Known Uses

The IBM Websphere Application Server [1] has a Connection Manager that acts as an intelligent, monitorable ConnectionFlyweight. Weblogic's Tengah [2] also pools connections.

lftp, a unix text-based FTP client, uses this approach. lftp allows for multiple concurrent downloads, rather than forcing you to wait for the first one to finish before you select the second download. If a download finishes just before you start a new download, it will use the old connection. (However, this window isn't very large, on the order of five seconds or so.)

Sybase Enterprise Application Server's [3] Jaguar CTS (Component Transaction Server) maintains a configurable pool of database connections that are allocated to server components as required. Called connection caching, pools of named, pre-allocated database connections to remote database servers are used to reduce overhead.


This sounds more like a cache pattern to me, a cheap way to get a usable connection by keeping a free list. I have to twist my mind to see a Flyweight in it. -- DaveHarris
To me, the introduction of flyweight into the pattern is important. Cache doesn't tell me anything about the structure of the situation. A cache could be a font cache that a word processor uses to avoid loading a font every time it experiences a certain typeface. A flyweight better implies that - in the case of a word processor - that a huge amount of objects could be requiring certain kinds of formatting or resources that are limited in number.

Another example: my web browser caches lots of content locally to improve performance; however my web server - especially when executing thousands of transactions at once - probably prefers a flyweight approach. But I'm open to your opinion...is 'cache' perhaps an alias of 'flyweight'? -- PhilipEskelin


Read the part of the Flyweight chapter that BobbyWoolf wrote in the DesignPatternsSmalltalkCompanion on when a cache is a flyweight and not and vice versa. Needless to say, the issue gets confusing because the terms aren't well defined. IMHO Flyweight didn't really get the participants right in GoF. (That's not heresy; when we wrote the DesignPatternsSmalltalkCompanion it turned out the GoF themselves didn't totally agree on the definition.) I think it's a Flyweight if you have the following three objects:

On the other hand, Flyweight makes a distinction between intrinsic and extrinsic data and implies some things about multithreading that don't apply here -- only one client can use the connection at any time, but multiple objects will share the connection over time. Still, I like the term Flyweight better than Cache so I'm sticking with it for now.

KyleBrown

Isn't a Flyweight used when the resources to be managed by the Flyweight are many and lightweight, thereby causing too much overhead if each is represented by an object? This seems to be the reverse - many small things sharing one large, heavyweight resource to avoid creation overhead. It seems to be an "upside-down" flyweight :-)

The term ConnectionPool seems to fit the bill a bit better IMHO. A ConnectionFlyweight/ConnectionPool has the same intent as a ThreadPool? -- that of reducing initialisation overhead for expensive resources -- except the resources are connections not threads.

Also, how does this relate to protocol multiplexing? A multiplexor would maintain a single expensive connection to each foreign address spaces and route multiple light-weight connections over each heavy-weight connection.

The difference seems to be the context: whether the heavy-weight connection can be used by many clients concurrently (multiplexor) or must be used one client at a time (pool).

--NatPryce

My take on this is that a multiplexor takes less-expensive things and uses a strategy (e.g., time-division multiplexing to assign time-slots they are given) to interact with the more-expensive things. There are other ways of course, depending on the protocol and medium, but still, it's not really a ConnectionFlyweight in my mind.

[I think the intent of a multiplexor is more to implement lightweight things (e.g: object bindings) using heavyweight things (e.g: TCP/IP connections) by sharing the expensive things among multiple light-weight things. I guess it can be visualised as layers: multiple lightweight bindings are layered on top of a single heavyweight connection. -- NatPryce]

And a pool is more of a set of live resources that can be used quickly by a changing set of clients. The intent of the pool as you mention is to eliminate the cost of creation and destruction of resources.

Now I think ConnectionFlyweight is similar to both of these patterns (I think a lot more similar to Connection Pool), but I think in the face of CBD that this pattern talks more about a huge number of clients (thousands for example at a given time) from everywhere trying to access a finite set of physical connections (say for example the connection flyweights are physical connections to databases). Perhaps the difference (if there is one) between a flyweight and pool is the number, location, and heterogeneity of clients using it where extrinsic state is used to set the context in a shared object that has common intrinsic state.

This will be a good thing to discuss at ChiliPLoP!

--PhilipEskelin

Now I'm unsure what you mean by "physical connection" in this pattern. Do you mean physical wire between client and server? Or do you mean transport connection or a connection at some higher protocol layer?

I guess we have three different patterns, ConnectionFlyweight, ConnectionPool and ConnectionMultiplexor?. The differences can be worked out by writing out the patterns and seeing the relationships between them. One difference between multiplexor and pool flyweight and multiplexor is in the context - whether the heavyweight resources can be shared or not.

--NatPryce


A resource that is worth to be pooled is exactly not fly-weight. If it were, I would not pool it. -- JuergenHermann


I don't have *Design Patterns* with me, but I thought the canonical example of a Flyweight is when you have a fixed number of immutable objects (characters from a character set) which are used many times (in paragraphs within in a word processor document), so you share them rather than creating lots of identical instances. As a result, each flyweight is the size of one pointer. The purpose of using a flyweight is to save memory when you need thousands of instantiations of the same object at the same time. (Simultaneous, nonexclusive reuse.)

A pool is a place to store objects while they are not being used. An object is removed from the pool in order to use it and then returned to the pool later. This is useful when objects are used temporarily, for non-overlapping timespans. (Serial, exclusive reuse.)

On the other hand in a cache, items are created, accessed, and later flushed to make room for other objects. (Not necessarily exclusive access - sometimes objects are returned by value.) Typically you have a large number of different objects, too many to store locally.

I think it makes sense to talk about a connection pool and a connection cache (it's really both). It probably only makes sense to have a connection flyweight if the connection is thread-safe and doesn't need to be returned. (Probably a singleton.)

BTW Google has about 2860 hits for "connection pool" and 1 for "connection flyweight".

- BrianSlesinsky


EditText of this page (last edited August 23, 2000)
FindPage by browsing or searching

This page mirrored in ComponentDesignPatterns as of April 29, 2006