fix: added configurable connection pool support for mssql (#38818)

## Description
With current implementation, MSSQL is configured with HikariCP to have
maximum pool size of 10. But this means that if multiple concurrent
users are accessing multiple queries of the same datasource at the same
time, some of the queries might time out due to max pool size of 10. We
have encountered this issue in
https://theappsmith.slack.com/archives/C0341RERY4R/p1736150680663059.
Where 40-50 concurrent users are simultaneously making 20-30 queries to
MSSQL database.


This PR makes this connection pool size configurable from admin settings
for MSSQL as well.


Fixes #https://github.com/appsmithorg/appsmith-ee/issues/5928
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12925650660>
> Commit: ebda9364200b4df19c86b8ec4e68a95d6180f10c
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12925650660&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Thu, 23 Jan 2025 11:18:35 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
	- Enhanced connection pool configuration for MSSQL plugin
	- Added support for dynamically setting maximum connection pool size

- **Improvements**
	- Increased flexibility in database connection management
	- Implemented configurable connection pool settings

- **Tests**
	- Added mock configuration for testing connection pool settings

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: “sneha122” <“sneha@appsmith.com”>
This commit is contained in:
sneha122 2025-02-01 00:36:19 +05:30 committed by GitHub
parent d538d0dc7d
commit b7c06d6c60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 7 deletions

View File

@ -1,5 +1,6 @@
package com.external.plugins;
import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig;
import com.appsmith.external.constants.DataType;
import com.appsmith.external.datatypes.AppsmithType;
import com.appsmith.external.dtos.ExecuteActionDTO;
@ -114,6 +115,12 @@ public class MssqlPlugin extends BasePlugin {
private static final int PREPARED_STATEMENT_INDEX = 0;
private final ConnectionPoolConfig connectionPoolConfig;
public MssqlPluginExecutor(ConnectionPoolConfig connectionPoolConfig) {
this.connectionPoolConfig = connectionPoolConfig;
}
/**
* Instead of using the default executeParametrized provided by pluginExecutor, this implementation affords an opportunity
* to use PreparedStatement (if configured) which requires the variable substitution, etc. to happen in a particular format
@ -356,9 +363,13 @@ public class MssqlPlugin extends BasePlugin {
@Override
public Mono<HikariDataSource> datasourceCreate(DatasourceConfiguration datasourceConfiguration) {
log.debug(Thread.currentThread().getName() + ": datasourceCreate() called for MSSQL plugin.");
return Mono.fromCallable(() -> {
log.debug(Thread.currentThread().getName() + ": Connecting to SQL Server db");
return createConnectionPool(datasourceConfiguration);
return connectionPoolConfig
.getMaxConnectionPoolSize()
.flatMap(maxPoolSize -> {
return Mono.fromCallable(() -> {
log.debug(Thread.currentThread().getName() + ": Connecting to SQL Server db");
return createConnectionPool(datasourceConfiguration, maxPoolSize);
});
})
.subscribeOn(scheduler);
}
@ -561,8 +572,8 @@ public class MssqlPlugin extends BasePlugin {
* @param datasourceConfiguration
* @return connection pool
*/
private static HikariDataSource createConnectionPool(DatasourceConfiguration datasourceConfiguration)
throws AppsmithPluginException {
private static HikariDataSource createConnectionPool(
DatasourceConfiguration datasourceConfiguration, Integer maxPoolSize) throws AppsmithPluginException {
DBAuth authentication = null;
StringBuilder urlBuilder = null;
@ -572,7 +583,11 @@ public class MssqlPlugin extends BasePlugin {
hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName(JDBC_DRIVER);
hikariConfig.setMinimumIdle(MINIMUM_POOL_SIZE);
hikariConfig.setMaximumPoolSize(MAXIMUM_POOL_SIZE);
// Use maxPoolSize from config if available, otherwise use default
int maximumPoolSize = maxPoolSize != null ? maxPoolSize : MAXIMUM_POOL_SIZE;
hikariConfig.setMaximumPoolSize(maximumPoolSize);
// Configuring leak detection threshold for 60 seconds. Any connection which hasn't been released in 60 seconds
// should get tracked (may be falsely for long running queries) as leaked connection
hikariConfig.setLeakDetectionThreshold(LEAK_DETECTION_TIME_MS);

View File

@ -1,5 +1,6 @@
package com.external.plugins;
import com.appsmith.external.configurations.connectionpool.ConnectionPoolConfig;
import com.appsmith.external.models.DBAuth;
import com.appsmith.external.models.DatasourceConfiguration;
import com.appsmith.external.models.Endpoint;
@ -8,6 +9,7 @@ import com.external.plugins.utils.MssqlDatasourceUtils;
import com.zaxxer.hikari.HikariDataSource;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.utility.DockerImageName;
import reactor.core.publisher.Mono;
import java.sql.SQLException;
import java.sql.Statement;
@ -18,7 +20,15 @@ import static com.external.plugins.utils.MssqlExecuteUtils.closeConnectionPostEx
public class MssqlTestDBContainerManager {
static MssqlPlugin.MssqlPluginExecutor mssqlPluginExecutor = new MssqlPlugin.MssqlPluginExecutor();
private static class MockConnectionPoolConfig implements ConnectionPoolConfig {
@Override
public Mono<Integer> getMaxConnectionPoolSize() {
return Mono.just(5);
}
}
static MssqlPlugin.MssqlPluginExecutor mssqlPluginExecutor =
new MssqlPlugin.MssqlPluginExecutor(new MockConnectionPoolConfig());
public static MssqlDatasourceUtils mssqlDatasourceUtils = new MssqlDatasourceUtils();