poco/Data/include/Poco/Data/SessionPool.h

239 lines
6.8 KiB
C++

//
// SessionPool.h
//
// Library: Data
// Package: SessionPooling
// Module: SessionPool
//
// Definition of the SessionPool class.
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Data_SessionPool_INCLUDED
#define Data_SessionPool_INCLUDED
#include "Poco/Data/Data.h"
#include "Poco/Data/PooledSessionHolder.h"
#include "Poco/Data/PooledSessionImpl.h"
#include "Poco/Data/Session.h"
#include "Poco/HashMap.h"
#include "Poco/Any.h"
#include "Poco/Timer.h"
#include "Poco/Mutex.h"
#include <list>
namespace Poco {
namespace Data {
class Data_API SessionPool: public RefCountedObject
/// This class implements session pooling for POCO Data.
///
/// Creating a connection to a database is often a time consuming
/// operation. Therefore it makes sense to reuse a session object
/// once it is no longer needed.
///
/// A SessionPool manages a collection of SessionImpl objects
/// (decorated with a PooledSessionImpl).
///
/// When a SessionImpl object is requested, the SessionPool first
/// looks in its set of already initialized SessionImpl for an
/// available object. If one is found, it is returned to the
/// client and marked as "in-use". If no SessionImpl is available,
/// the SessionPool attempts to create a new one for the client.
/// To avoid excessive creation of SessionImpl objects, a limit
/// can be set on the maximum number of objects.
/// Sessions found not to be connected to the database are purged
/// from the pool whenever one of the following events occurs:
///
/// - JanitorTimer event
/// - get() request
/// - putBack() request
///
/// Not connected idle sessions can not exist.
///
/// Usage example:
///
/// SessionPool pool("ODBC", "...");
/// ...
/// Session sess(pool.get());
/// ...
{
public:
SessionPool(const std::string& connector,
const std::string& connectionString,
int minSessions = 1,
int maxSessions = 32,
int idleTime = 60,
int connTimeout = 60);
/// Creates the SessionPool for sessions with the given connector
/// and connectionString.
///
/// The pool allows for at most maxSessions sessions to be created.
/// If a session has been idle for more than idleTime seconds, and more than
/// minSessions sessions are in the pool, the session is automatically destroyed.
~SessionPool();
/// Destroys the SessionPool.
Session get();
/// Returns a Session.
///
/// If there are unused sessions available, one of the
/// unused sessions is recycled. Otherwise, a new session
/// is created.
///
/// If the maximum number of sessions for this pool has
/// already been created, a SessionPoolExhaustedException
/// is thrown.
template <typename T>
Session get(const std::string& name, const T& value)
/// Returns a Session with requested property set.
/// The property can be different from the default pool
/// value, in which case it is reset back to the pool
/// value when the session is reclaimed by the pool.
{
Session s = get();
_addPropertyMap.insert(AddPropertyMap::value_type(s.impl(),
std::make_pair(name, s.getProperty(name))));
s.setProperty(name, value);
return s;
}
Session get(const std::string& name, bool value);
/// Returns a Session with requested feature set.
/// The feature can be different from the default pool
/// value, in which case it is reset back to the pool
/// value when the session is reclaimed by the pool.
int capacity() const;
/// Returns the maximum number of sessions the SessionPool will manage.
int used() const;
/// Returns the number of sessions currently in use.
int idle() const;
/// Returns the number of idle sessions.
int connTimeout() const;
/// Returns the connection timeout.
int dead();
/// Returns the number of not connected active sessions.
int allocated() const;
/// Returns the number of allocated sessions.
int available() const;
/// Returns the number of available (idle + remaining capacity) sessions.
std::string name() const;
/// Returns the name for this pool.
static std::string name(const std::string& connector,
const std::string& connectionString);
/// Returns the name formatted from supplied arguments as "connector:///connectionString".
void setFeature(const std::string& name, bool state);
/// Sets feature for all the sessions.
bool getFeature(const std::string& name) const;
/// Returns the requested feature.
void setProperty(const std::string& name, const Poco::Any& value);
/// Sets property for all sessions.
Poco::Any getProperty(const std::string& name) const;
/// Returns the requested property.
void shutdown();
/// Shuts down the session pool.
bool isActive() const;
/// Returns true if session pool is active (not shut down).
protected:
virtual void customizeSession(Session& session);
/// Can be overridden by subclass to perform custom initialization
/// of a newly created database session.
///
/// The default implementation does nothing.
typedef Poco::AutoPtr<PooledSessionHolder> PooledSessionHolderPtr;
typedef Poco::AutoPtr<PooledSessionImpl> PooledSessionImplPtr;
typedef std::list<PooledSessionHolderPtr> SessionList;
typedef Poco::HashMap<std::string, bool> FeatureMap;
typedef Poco::HashMap<std::string, Poco::Any> PropertyMap;
void purgeDeadSessions();
int deadImpl(SessionList& rSessions);
void applySettings(SessionImpl* pImpl);
void putBack(PooledSessionHolderPtr pHolder);
void onJanitorTimer(Poco::Timer&);
private:
typedef std::pair<std::string, Poco::Any> PropertyPair;
typedef std::pair<std::string, bool> FeaturePair;
typedef std::map<SessionImpl*, PropertyPair> AddPropertyMap;
typedef std::map<SessionImpl*, FeaturePair> AddFeatureMap;
SessionPool(const SessionPool&);
SessionPool& operator = (const SessionPool&);
void closeAll(SessionList& sessionList);
std::string _connector;
std::string _connectionString;
std::atomic<int> _minSessions;
std::atomic<int> _maxSessions;
std::atomic<int> _idleTime;
std::atomic<int> _connTimeout;
std::atomic<int> _nSessions;
SessionList _idleSessions;
SessionList _activeSessions;
Poco::Timer _janitorTimer;
FeatureMap _featureMap;
PropertyMap _propertyMap;
std::atomic<bool> _shutdown;
AddPropertyMap _addPropertyMap;
AddFeatureMap _addFeatureMap;
mutable
Poco::Mutex _mutex;
friend class PooledSessionImpl;
};
inline std::string SessionPool::name(const std::string& connector,
const std::string& connectionString)
{
return Session::uri(connector, connectionString);
}
inline std::string SessionPool::name() const
{
return name(_connector, _connectionString);
}
inline bool SessionPool::isActive() const
{
return !_shutdown;
}
} } // namespace Poco::Data
#endif // Data_SessionPool_INCLUDED