16#ifndef QGSCONNECTIONPOOL_H
17#define QGSCONNECTIONPOOL_H
26#include <QCoreApplication>
27#include <QElapsedTimer>
37using namespace Qt::StringLiterals;
39#define CONN_POOL_EXPIRATION_TIME 60
40#define CONN_POOL_SPARE_CONNECTIONS 2
89 for (
const Item &item : std::as_const(
conns ) )
91 qgsConnectionPool_ConnectionDestroy( item.c );
105 T
acquire(
int timeout,
bool requestMayBeNested )
108 const int requiredFreeConnectionCount = requestMayBeNested ? 1 : 3;
112 if ( !
sem.tryAcquire( requiredFreeConnectionCount, timeout ) )
124 sem.acquire( requiredFreeConnectionCount );
126 sem.release( requiredFreeConnectionCount - 1 );
132 if ( !
conns.isEmpty() )
136 if ( !qgsConnectionPool_ConnectionIsValid( i.
c ) )
139 qgsConnectionPool_ConnectionDestroy( i.
c );
141 qgsConnectionPool_ConnectionCreate(
connInfo, i.
c );
146 if (
conns.isEmpty() )
149 QMetaObject::invokeMethod(
expirationTimer->parent(),
"stopExpirationTimer" );
161 qgsConnectionPool_ConnectionCreate(
connInfo,
c );
171 QgsDebugMsgLevel( u
"Acquired connection with name: %1"_s.arg( qgsConnectionPool_ConnectionToName(
c ) ), 2 );
182 if ( !qgsConnectionPool_ConnectionIsValid( conn ) )
185 qgsConnectionPool_ConnectionDestroy( conn );
197 QMetaObject::invokeMethod(
expirationTimer->parent(),
"startExpirationTimer" );
210 for (
const Item &i : std::as_const(
conns ) )
212 qgsConnectionPool_ConnectionDestroy( i.c );
216 qgsConnectionPool_InvalidateConnection(
c );
233 QObject::connect(
expirationTimer, &QTimer::timeout, parent, &U::handleConnectionExpired );
237 parent->moveToThread( qApp->thread() );
244 QTime now = QTime::currentTime();
248 for (
int i = 0; i <
conns.count(); ++i )
251 toDelete.append( i );
255 for (
int j = toDelete.count() - 1; j >= 0; --j )
257 int index = toDelete[j];
258 qgsConnectionPool_ConnectionDestroy(
conns[index].
c );
259 conns.remove( index );
262 if (
conns.isEmpty() )
297template <
typename T,
typename T_Group>
308 for (
auto it =
mGroups.constBegin(); it !=
mGroups.constEnd(); ++it )
310 QgsDebugMsgLevel( u
"Destroying connection pool group with key %1"_s.arg( it.key() ), 2 );
330 QgsDebugMsgLevel( u
"Trying to acquire connection for %1"_s.arg( connInfo ), 2 );
332 typename T_Groups::iterator it =
mGroups.find( connInfo );
336 it =
mGroups.insert( connInfo,
new T_Group( connInfo ) );
342 T_Group *group = *it;
350 while ( !feedback->isCanceled() )
352 if ( T conn = group->acquire( 300, requestMayBeNested ) )
355 if ( timeout > 0 && timer.elapsed() >= timeout )
362 return group->acquire( timeout, requestMayBeNested );
370 const QString groupName = qgsConnectionPool_ConnectionToName( conn );
372 typename T_Groups::iterator it =
mGroups.find( groupName );
373 Q_ASSERT( it !=
mGroups.end() );
374 T_Group *group = *it;
378 group->release( conn );
390 QgsDebugMsgLevel( u
"Invalidating connections for %1"_s.arg( connInfo ), 2 );
393 auto it =
mGroups.constFind( connInfo );
394 if ( it !=
mGroups.constEnd() )
397 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)