16#ifndef QGSCONNECTIONPOOL_H
17#define QGSCONNECTIONPOOL_H
25#include <QCoreApplication>
26#include <QElapsedTimer>
38using namespace Qt::StringLiterals;
40#define CONN_POOL_EXPIRATION_TIME 60
41#define CONN_POOL_SPARE_CONNECTIONS 2
90 for (
const Item &item : std::as_const(
conns ) )
92 qgsConnectionPool_ConnectionDestroy( item.c );
106 T
acquire(
int timeout,
bool requestMayBeNested )
109 const int requiredFreeConnectionCount = requestMayBeNested ? 1 : 3;
113 if ( !
sem.tryAcquire( requiredFreeConnectionCount, timeout ) )
125 sem.acquire( requiredFreeConnectionCount );
127 sem.release( requiredFreeConnectionCount - 1 );
133 if ( !
conns.isEmpty() )
137 if ( !qgsConnectionPool_ConnectionIsValid( i.
c ) )
140 qgsConnectionPool_ConnectionDestroy( i.
c );
142 qgsConnectionPool_ConnectionCreate(
connInfo, i.
c );
147 if (
conns.isEmpty() )
150 QMetaObject::invokeMethod(
expirationTimer->parent(),
"stopExpirationTimer" );
162 qgsConnectionPool_ConnectionCreate(
connInfo,
c );
172 QgsDebugMsgLevel( u
"Acquired connection with name: %1"_s.arg( qgsConnectionPool_ConnectionToName(
c ) ), 2 );
183 if ( !qgsConnectionPool_ConnectionIsValid( conn ) )
186 qgsConnectionPool_ConnectionDestroy( conn );
198 QMetaObject::invokeMethod(
expirationTimer->parent(),
"startExpirationTimer" );
211 for (
const Item &i : std::as_const(
conns ) )
213 qgsConnectionPool_ConnectionDestroy( i.c );
217 qgsConnectionPool_InvalidateConnection(
c );
234 QObject::connect(
expirationTimer, &QTimer::timeout, parent, &U::handleConnectionExpired );
238 parent->moveToThread( qApp->thread() );
245 QTime now = QTime::currentTime();
249 for (
int i = 0; i <
conns.count(); ++i )
252 toDelete.append( i );
256 for (
int j = toDelete.count() - 1; j >= 0; --j )
258 int index = toDelete[j];
259 qgsConnectionPool_ConnectionDestroy(
conns[index].
c );
260 conns.remove( index );
263 if (
conns.isEmpty() )
298template <
typename T,
typename T_Group>
309 for (
auto it =
mGroups.constBegin(); it !=
mGroups.constEnd(); ++it )
311 QgsDebugMsgLevel( u
"Destroying connection pool group with key %1"_s.arg( it.key() ), 2 );
331 QgsDebugMsgLevel( u
"Trying to acquire connection for %1"_s.arg( connInfo ), 2 );
333 typename T_Groups::iterator it =
mGroups.find( connInfo );
337 it =
mGroups.insert( connInfo,
new T_Group( connInfo ) );
343 T_Group *group = *it;
351 while ( !feedback->isCanceled() )
353 if ( T conn = group->acquire( 300, requestMayBeNested ) )
356 if ( timeout > 0 && timer.elapsed() >= timeout )
363 return group->acquire( timeout, requestMayBeNested );
371 const QString groupName = qgsConnectionPool_ConnectionToName( conn );
373 typename T_Groups::iterator it =
mGroups.find( groupName );
374 Q_ASSERT( it !=
mGroups.end() );
375 T_Group *group = *it;
379 group->release( conn );
391 QgsDebugMsgLevel( u
"Invalidating connections for %1"_s.arg( connInfo ), 2 );
394 auto it =
mGroups.constFind( connInfo );
395 if ( it !=
mGroups.constEnd() )
398 it.value()->invalidateConnections();
Extends QApplication to provide access to QGIS specific resources such as theme paths,...
void invalidateConnections()
QgsConnectionPoolGroup(const QgsConnectionPoolGroup &other)=delete
T acquire(int timeout, bool requestMayBeNested)
Try to acquire a connection for a maximum of timeout milliseconds.
void initTimer(U *parent)
Initializes the connection timeout handling.
QgsConnectionPoolGroup(const QString &ci)
Constructor for QgsConnectionPoolGroup, with the specified connection info.
QgsConnectionPoolGroup & operator=(const QgsConnectionPoolGroup &other)=delete
~QgsConnectionPoolGroup()
void onConnectionExpired()
Template class responsible for keeping a pool of open connections.
QMap< QString, T_Group * > T_Groups
void invalidateConnections(const QString &connInfo)
Invalidates all connections to the specified resource.
virtual ~QgsConnectionPool()
T acquireConnection(const QString &connInfo, int timeout=-1, bool requestMayBeNested=false, QgsFeedback *feedback=nullptr)
Try to acquire a connection for a maximum of timeout milliseconds.
void releaseConnection(T conn)
Release an existing connection so it will get back into the pool and can be reused.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define CONN_POOL_SPARE_CONNECTIONS
#define CONN_POOL_EXPIRATION_TIME
#define QgsDebugMsgLevel(str, level)