Is there any reason for an object pool to not be treated as a singleton?
Asked Answered
B

3

8

I don't necessarily mean implemented using the singleton pattern, but rather, only having and using one instance of a pool. I don't like the idea of having just one pool (or one per pooled type). However, I can't really come up with any concrete situations where there's an advantage to multiple pools for mutable types, at least not any where a single pool can function just as well.

What advantages are there to having multiple pools over a singleton pool?

Barny answered 9/2, 2011 at 19:24 Comment(1)
I wonder if how I've used object pools (memory/lifetime management of simple, reusable objects) has affected how I understand these answers. App pools, thread pools, connection pools vs my understanding of object pools feels very apples vs oranges to me.Barny
H
2

What advantages are there to having multiple pools over a singleton pool?

I supposed most object pools we use, like the ThreadPool, are implemented as singletons for simplicity: in that, the designers of those pools didn't see a purpose in multiple-instance pools either.

However, there are a handful of places where we really do have multiple pools: IIS application pools and database connection pools.

App pools

In IIS, you can configure multiple application pools, so that related web applications all run in their own pool. There are a couple of advantages to this design, and the advantages can generalize to pool implementations outside of IIS:

  • Multiple object pools allow for some degree of isolation, so an error in one pool should not have an impact on objects in other pools.

  • Each pool can run under a different user, which gives you different levels of security based on your application pool.

  • Each pool can have a different handler for errors.

  • Each pool can run with a different version of the .NET framework.

  • Each pool can have its own HTTP timeout.

Connection pools

In SQL Server, multiple calls to a database use connection pooling to avoid the overhead of creating a new database connection on every query, however SQL Server creates a new pool per connection string. I imagine the rationale behind this design is as follows:

  • Each pool holds a connection to a specific database instance. If there were only one pool containing all the connections, then it would need search through all the connections until it finds the connection matching the connection string you've requested. Since there are multiple pools per connection string, its easier to pull the first available connection from that particular pool without searching through other connections.

  • In other words, I suspect SQL Server uses multiple connection pools as an optimization to quickly grab a database connection.

  • I can also imagine that all of those connections probably share some resources specific to their connection pool, which may not be possible with a single pool. For example, you can specify the maximum connection pool size per connection string; you may not be able to control the number of simultaneous connections to a particular database using a single-pool design.

How to design a pool

You can't really choose whether to have multiple pools or a single pool without looking at what you really need from your design.

If you have a very simple object pool, you might be able to get away with a singleton design. If you really need extra flexibility, customization, or maybe you have a really unique setup like an object pool distributed across multiple processes or machines, you would definitely benefit from an n-gleton design instead.

Hau answered 9/2, 2011 at 22:55 Comment(1)
App and connection pools feel like apples vs oranges for how I've used object pools. I can certainly see the benefits for them to not be singletons, but it's hard for me to compare them against my own pool use. It's probably a failure on my part, but I can't help but approach pools from a memory/lifetime management perspective -- I've only used them to cut down on having to create and destroy objects continually.Barny
D
3

Yes, there are definitely potential reasons for having multiple object pools - in particular, you may want to let one pool become eligible for garbage collection (or manually free it etc) while keeping other ones.

For example, consider an object pool for strings. That may be really handy in the context of XML - if you're parsing several XML documents of the same schema, you quite possibly want to pool the strings used for the element and attribute names. However, once you've finished that part of processing those names may never be used again - so as you move onto a different set of documents, you may want to use a different pool. You may end up doing both tasks at once, in which case it's useful to have both pools available simultaneously.

Or consider thread pools - I consider it a downside of the .NET thread pool implementation that there's basically just one system thread pool. I like the idea of being able to have multiple thread pools in a server - some threads for low priority batch jobs, some for "normal" requests, and a few high priority threads for jobs like health monitoring.

Drunkard answered 9/2, 2011 at 19:28 Comment(4)
I'm thinking of a pool for mutable, short-lived objects, though. (I guess I should have mentioned that in the question.) I can see how multiple pools for something like string would be useful, but can't really think how to apply that to the needs of managing something like entities in a game engine. Thread pool's a good example though!Barny
@Chris: A game engine is typically running just one game, of course. Imagine writing a game server however, which was coordinating several games. Each of those games could want its own pool...Drunkard
My own experience with game servers is that you never have one that coordinates more than one game per process. That might be different with MMOGs but I've never worked on one of those, and certainly never hosted a server for one.Barny
@Chris: It obviously depends on the kind of game, but I'd imagine that there are plenty of games where there's relatively light interaction with the client, and where you wouldn't want one process per game.Drunkard
H
2

What advantages are there to having multiple pools over a singleton pool?

I supposed most object pools we use, like the ThreadPool, are implemented as singletons for simplicity: in that, the designers of those pools didn't see a purpose in multiple-instance pools either.

However, there are a handful of places where we really do have multiple pools: IIS application pools and database connection pools.

App pools

In IIS, you can configure multiple application pools, so that related web applications all run in their own pool. There are a couple of advantages to this design, and the advantages can generalize to pool implementations outside of IIS:

  • Multiple object pools allow for some degree of isolation, so an error in one pool should not have an impact on objects in other pools.

  • Each pool can run under a different user, which gives you different levels of security based on your application pool.

  • Each pool can have a different handler for errors.

  • Each pool can run with a different version of the .NET framework.

  • Each pool can have its own HTTP timeout.

Connection pools

In SQL Server, multiple calls to a database use connection pooling to avoid the overhead of creating a new database connection on every query, however SQL Server creates a new pool per connection string. I imagine the rationale behind this design is as follows:

  • Each pool holds a connection to a specific database instance. If there were only one pool containing all the connections, then it would need search through all the connections until it finds the connection matching the connection string you've requested. Since there are multiple pools per connection string, its easier to pull the first available connection from that particular pool without searching through other connections.

  • In other words, I suspect SQL Server uses multiple connection pools as an optimization to quickly grab a database connection.

  • I can also imagine that all of those connections probably share some resources specific to their connection pool, which may not be possible with a single pool. For example, you can specify the maximum connection pool size per connection string; you may not be able to control the number of simultaneous connections to a particular database using a single-pool design.

How to design a pool

You can't really choose whether to have multiple pools or a single pool without looking at what you really need from your design.

If you have a very simple object pool, you might be able to get away with a singleton design. If you really need extra flexibility, customization, or maybe you have a really unique setup like an object pool distributed across multiple processes or machines, you would definitely benefit from an n-gleton design instead.

Hau answered 9/2, 2011 at 22:55 Comment(1)
App and connection pools feel like apples vs oranges for how I've used object pools. I can certainly see the benefits for them to not be singletons, but it's hard for me to compare them against my own pool use. It's probably a failure on my part, but I can't help but approach pools from a memory/lifetime management perspective -- I've only used them to cut down on having to create and destroy objects continually.Barny
R
0

If you implement a singleton pattern carefully, you can change your mind later. Just encapsulate your class's singleton-ness behind a factory method. If everything uses that, then you can allow it to have multiple instances later, when you have a good reason.

public class MyClass
{
    public static MyClass GetInstance()
    {
          return singleton_ ?? (singleton = new MyClass());
    }
}
Romine answered 13/2, 2011 at 15:21 Comment(1)
That doesn't answer the question. This is not about hows, this is about whys.Barny

© 2022 - 2024 — McMap. All rights reserved.