The other day there was a thread in a newsgroup which ended up discussing object pooling. Jon pointed to Spring.NET – an application framework for enterprise .NET applications. I’m sure there are other implementations out there, at the moment, Spring.NET merely offers a few interfaces and a rather simplistic implementation of a pool. I thought it might be interesting to people to see how pooling functionality can be implemented, so I’m going to do that for this article, which is supposed to be a first in a small series.
What is an object pool?
I’m going to apply my own definition here, which is rather unassuming in nature: An object pool is a object that holds a list of other objects, ready to make them available for use (to yet another object, probably). It does the management work involved, like keeping track of which objects are currently in use, how many objects the pool holds, whether this number should be increased… Where do you use this? Most commonly it’s used in server systems where services are made available to a number of clients: by having a pre-created pool of objects, the server can quickly react to new requests without having to wait for a new object to be constructed; if the pool scales well, the system will adapt easily to different load levels.
To start with, there’s got to be some conceptual thinking: what exactly is it that this object pool is supposed to do, which requirements does it have? So, here’s what I’m setting out to create:
- The object pool should be reusable and type independent.
- The pool must be thread safe.
- It should be scaleable. The exact way in which the pool can grow and shrink should be configurable.
- Work with objects from the pool should be safe. There’s got to be a mechanism to make sure that objects are in a stable state when returned to the pool.
- Flexibility. I’d like the pool object to support various configurations configurably, instead of creating various pool classes for different detail approaches.
This doesn’t have to be it – I suppose I’ll make up additional features while I go along :-). But these are the main guidelines for now.
Reusability, type independence
One initial question is this: Do we achieve type independence by letting the pool handle interfaces instead of concrete types, or do we use a generic class for even better type safety? In this case I think the generic class is a better choice, because using interfaces would make the single poolable object more complex. What’s more, we don’t really need anything from the object, so what methods should that interface contain? No, I think I’m going to make the pool a generic class, the generic parameter being the type of the pooled object.
I must assume that objects from the pool are going to be requested from more than one thread, so all management functions must be thread safe. This should be achieved quite easily, because the pool will have only one important central structure: the list of objects in the pool.
A pool can have a static size, so scalability is not a problem. But it’s also possible that the pool has to grow when more objects are needed, and to shrink when the number of unused objects is too large. This is a complex topic because there are many different approaches. For example, do we let the pool grow when we find out that no objects are left, or do we try to find out about the need for more objects before we run out? If the latter, how? Also, when more objects have to be created, who does that? We’ll need a factory for that, because the pool itself doesn’t know how to create new objects of the pooled type and we don’t want to impose arbitrary restrictions such as the availability of a default constructor. Lots to think about here and a number of options.
Safety of pool objects
When an object that utilizes the pool gets an object out of it and starts work with it, it must not find out a moment later that old state information has been left in the object (or probably it won’t find out, the results that it gets from the object will simply be wrong). So, depending on the implementation of the pooled objects, it might be necessary to check the validity of the object state when an object is returned to the pool.
With regard to many of the topics discussed above, there may be more than one possible approach. I’d like the pool to implement several alternatives in those cases, the programmer using the pool should be able to switch those behaviours even at runtime. I think this makes more sense than to implement a complete hierarchy of different pool classes, each with various differences in detail implementations.
So, this is it for now, watch this space for part 2, coming soon! And please comment if you have additional ideas!