Skip to content

Commit 7c8c6ca

Browse files
committed
Allow specifying the number of required connections
for a request. Most requests should reserve more than a single connection (default: 3) and only requests that are executed as nested expressions should specify 1.
1 parent 71f9910 commit 7c8c6ca

File tree

5 files changed

+90
-7
lines changed

5 files changed

+90
-7
lines changed

python/core/auto_generated/qgsfeaturerequest.sip.in

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,40 @@ at this moment. A negative value (which is set by default) will wait forever.
657657
Only works if the provider supports this option.
658658

659659
.. versionadded:: 3.0
660+
%End
661+
662+
int freeConnectionsRequirement() const;
663+
%Docstring
664+
The amount of free connections required to start this request.
665+
The system will block the request until the specified amount of connections
666+
is available for usage.
667+
668+
By default this amount is 3. This makes sure, that we have 2 spare connections
669+
that might be used by "nested" requests which are executed while iterating
670+
over the results of this request.
671+
672+
This number should be changed to one, when we know that no nested requests happen
673+
and that this request might happen in a nested way. This is for example given for
674+
expression functions that do internal requests.
675+
676+
.. versionadded:: 3.4
677+
%End
678+
679+
void setFreeConnectionsRequirement( int freeConnectionsRequirement );
680+
%Docstring
681+
The amount of free connections required to start this request.
682+
The system will block the request until the specified amount of connections
683+
is available for usage.
684+
685+
By default this amount is 3. This makes sure, that we have 2 spare connections
686+
that might be used by "nested" requests which are executed while iterating
687+
over the results of this request.
688+
689+
This number should be changed to one, when we know that no nested requests happen
690+
and that this request might happen in a nested way. This is for example given for
691+
expression functions that do internal requests.
692+
693+
.. versionadded:: 3.4
660694
%End
661695

662696
protected:

src/core/qgsconnectionpool.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include <QThread>
3030

3131

32-
#define CONN_POOL_MAX_CONCURRENT_CONNS 4
32+
#define CONN_POOL_MAX_CONCURRENT_CONNS 6
3333
#define CONN_POOL_EXPIRATION_TIME 60 // in seconds
3434

3535

@@ -93,12 +93,12 @@ class QgsConnectionPoolGroup
9393
*
9494
* \returns initialized connection or nullptr if unsuccessful
9595
*/
96-
T acquire( int timeout )
96+
T acquire( int timeout, int freeConnectionRequirement )
9797
{
9898
// we are going to acquire a resource - if no resource is available, we will block here
9999
if ( timeout >= 0 )
100100
{
101-
if ( !sem.tryAcquire( 1, timeout ) )
101+
if ( !sem.tryAcquire( freeConnectionRequirement, timeout ) )
102102
return nullptr;
103103
}
104104
else
@@ -107,8 +107,9 @@ class QgsConnectionPoolGroup
107107
// tryAcquire is broken on Qt > 5.8 with negative timeouts - see
108108
// https://bugreports.qt.io/browse/QTBUG-64413
109109
// https://lists.osgeo.org/pipermail/qgis-developer/2017-November/050456.html
110-
sem.acquire( 1 );
110+
sem.acquire( freeConnectionRequirement );
111111
}
112+
sem.release( freeConnectionRequirement - 1 );
112113

113114
// quick (preferred) way - use cached connection
114115
{
@@ -283,9 +284,11 @@ class QgsConnectionPool
283284
* If \a timeout is a negative value the calling thread will be blocked
284285
* until a connection becomes available. This is the default behavior.
285286
*
287+
*
288+
*
286289
* \returns initialized connection or nullptr if unsuccessful
287290
*/
288-
T acquireConnection( const QString &connInfo, int timeout = -1 )
291+
T acquireConnection( const QString &connInfo, int timeout = -1, int freeConnectionRequirement = 3 )
289292
{
290293
mMutex.lock();
291294
typename T_Groups::iterator it = mGroups.find( connInfo );
@@ -296,7 +299,7 @@ class QgsConnectionPool
296299
T_Group *group = *it;
297300
mMutex.unlock();
298301

299-
return group->acquire( timeout );
302+
return group->acquire( timeout, freeConnectionRequirement );
300303
}
301304

302305
//! Release an existing connection so it will get back into the pool and can be reused

src/core/qgsfeaturerequest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ QgsFeatureRequest &QgsFeatureRequest::operator=( const QgsFeatureRequest &rh )
8686
mCrs = rh.mCrs;
8787
mTransformErrorCallback = rh.mTransformErrorCallback;
8888
mConnectionTimeout = rh.mConnectionTimeout;
89+
mFreeConnectionsRequirement = rh.mFreeConnectionsRequirement;
8990
return *this;
9091
}
9192

@@ -298,6 +299,16 @@ void QgsFeatureRequest::setConnectionTimeout( int connectionTimeout )
298299
mConnectionTimeout = connectionTimeout;
299300
}
300301

302+
int QgsFeatureRequest::freeConnectionsRequirement() const
303+
{
304+
return mFreeConnectionsRequirement;
305+
}
306+
307+
void QgsFeatureRequest::setFreeConnectionsRequirement( int freeConnectionsRequirement )
308+
{
309+
mFreeConnectionsRequirement = freeConnectionsRequirement;
310+
}
311+
301312

302313
#include "qgsfeatureiterator.h"
303314
#include "qgslogger.h"

src/core/qgsfeaturerequest.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,40 @@ class CORE_EXPORT QgsFeatureRequest
636636
*/
637637
void setConnectionTimeout( int connectionTimeout );
638638

639+
/**
640+
* The amount of free connections required to start this request.
641+
* The system will block the request until the specified amount of connections
642+
* is available for usage.
643+
*
644+
* By default this amount is 3. This makes sure, that we have 2 spare connections
645+
* that might be used by "nested" requests which are executed while iterating
646+
* over the results of this request.
647+
*
648+
* This number should be changed to one, when we know that no nested requests happen
649+
* and that this request might happen in a nested way. This is for example given for
650+
* expression functions that do internal requests.
651+
*
652+
* \since QGIS 3.4
653+
*/
654+
int freeConnectionsRequirement() const;
655+
656+
/**
657+
* The amount of free connections required to start this request.
658+
* The system will block the request until the specified amount of connections
659+
* is available for usage.
660+
*
661+
* By default this amount is 3. This makes sure, that we have 2 spare connections
662+
* that might be used by "nested" requests which are executed while iterating
663+
* over the results of this request.
664+
*
665+
* This number should be changed to one, when we know that no nested requests happen
666+
* and that this request might happen in a nested way. This is for example given for
667+
* expression functions that do internal requests.
668+
*
669+
* \since QGIS 3.4
670+
*/
671+
void setFreeConnectionsRequirement( int freeConnectionsRequirement );
672+
639673
protected:
640674
FilterType mFilter = FilterNone;
641675
QgsRectangle mFilterRect;
@@ -654,6 +688,7 @@ class CORE_EXPORT QgsFeatureRequest
654688
QgsCoordinateReferenceSystem mCrs;
655689
QgsCoordinateTransformContext mTransformContext;
656690
int mConnectionTimeout = -1;
691+
int mFreeConnectionsRequirement = 3;
657692
};
658693

659694
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsFeatureRequest::Flags )

src/providers/postgres/qgspostgresfeatureiterator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource
3838

3939
if ( !source->mTransactionConnection )
4040
{
41-
mConn = QgsPostgresConnPool::instance()->acquireConnection( mSource->mConnInfo );
41+
mConn = QgsPostgresConnPool::instance()->acquireConnection( mSource->mConnInfo, request.connectionTimeout(), request.freeConnectionsRequirement() );
4242
mIsTransactionConnection = false;
4343
}
4444
else

0 commit comments

Comments
 (0)