16#ifndef QGSCONNECTIONPOOL_H
17#define QGSCONNECTIONPOOL_H
26#include <QCoreApplication>
27#include <QElapsedTimer>
36#define CONN_POOL_EXPIRATION_TIME 60
37#define CONN_POOL_SPARE_CONNECTIONS 2
86 for (
const Item &item : std::as_const(
conns ) )
88 qgsConnectionPool_ConnectionDestroy( item.c );
102 T
acquire(
int timeout,
bool requestMayBeNested )
105 const int requiredFreeConnectionCount = requestMayBeNested ? 1 : 3;
109 if ( !
sem.tryAcquire( requiredFreeConnectionCount, timeout ) )
121 sem.acquire( requiredFreeConnectionCount );
123 sem.release( requiredFreeConnectionCount - 1 );
129 if ( !
conns.isEmpty() )
131 QgsDebugMsgLevel( QStringLiteral(
"Trying to use existing connection" ), 2 );
133 if ( !qgsConnectionPool_ConnectionIsValid( i.
c ) )
135 QgsDebugMsgLevel( QStringLiteral(
"Connection is not valid, destroying" ), 2 );
136 qgsConnectionPool_ConnectionDestroy( i.
c );
138 qgsConnectionPool_ConnectionCreate(
connInfo, i.
c );
143 if (
conns.isEmpty() )
146 QMetaObject::invokeMethod(
expirationTimer->parent(),
"stopExpirationTimer" );
158 qgsConnectionPool_ConnectionCreate(
connInfo,
c );
168 QgsDebugMsgLevel( QStringLiteral(
"Acquired connection with name: %1" ).arg( qgsConnectionPool_ConnectionToName(
c ) ), 2 );
179 if ( !qgsConnectionPool_ConnectionIsValid( conn ) )
182 qgsConnectionPool_ConnectionDestroy( conn );
194 QMetaObject::invokeMethod(
expirationTimer->parent(),
"startExpirationTimer" );
205 QgsDebugMsgLevel( QStringLiteral(
"Invalidating connections for group" ), 2 );
207 for (
const Item &i : std::as_const(
conns ) )
209 qgsConnectionPool_ConnectionDestroy( i.c );
213 qgsConnectionPool_InvalidateConnection(
c );
230 QObject::connect(
expirationTimer, &QTimer::timeout, parent, &U::handleConnectionExpired );
234 parent->moveToThread( qApp->thread() );
241 QTime now = QTime::currentTime();
245 for (
int i = 0; i <
conns.count(); ++i )
248 toDelete.append( i );
252 for (
int j = toDelete.count() - 1; j >= 0; --j )
254 int index = toDelete[j];
255 qgsConnectionPool_ConnectionDestroy(
conns[index].
c );
256 conns.remove( index );
259 if (
conns.isEmpty() )
294template <
typename T,
typename T_Group>
305 for (
auto it =
mGroups.constBegin(); it !=
mGroups.constEnd(); ++it )
307 QgsDebugMsgLevel( QStringLiteral(
"Destroying connection pool group with key %1" ).arg( it.key() ), 2 );
310 QgsDebugMsgLevel( QStringLiteral(
"Connection pool groups destroyed" ), 2 );
327 QgsDebugMsgLevel( QStringLiteral(
"Trying to acquire connection for %1" ).arg( connInfo ), 2 );
329 typename T_Groups::iterator it =
mGroups.find( connInfo );
332 QgsDebugMsgLevel( QStringLiteral(
"Could not find existing group, adding new one" ), 2 );
333 it =
mGroups.insert( connInfo,
new T_Group( connInfo ) );
339 T_Group *group = *it;
347 while ( !feedback->isCanceled() )
349 if ( T conn = group->acquire( 300, requestMayBeNested ) )
352 if ( timeout > 0 && timer.elapsed() >= timeout )
359 return group->acquire( timeout, requestMayBeNested );
367 const QString groupName = qgsConnectionPool_ConnectionToName( conn );
368 QgsDebugMsgLevel( QStringLiteral(
"Releasing connection for %1" ).arg( groupName ), 2 );
369 typename T_Groups::iterator it =
mGroups.find( groupName );
370 Q_ASSERT( it !=
mGroups.end() );
371 T_Group *group = *it;
375 group->release( conn );
387 QgsDebugMsgLevel( QStringLiteral(
"Invalidating connections for %1" ).arg( connInfo ), 2 );
390 auto it =
mGroups.constFind( connInfo );
391 if ( it !=
mGroups.constEnd() )
394 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)