Skip to content

Commit

Permalink
SNOW-902608 - new pool version implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-mhofman committed Oct 11, 2023
1 parent ceef6c4 commit 73bb45c
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 33 deletions.
56 changes: 44 additions & 12 deletions Snowflake.Data/Client/SnowflakeDbConnectionPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
*/

using System;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -14,72 +15,103 @@ namespace Snowflake.Data.Client
public class SnowflakeDbConnectionPool
{
private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger<SnowflakeDbConnectionPool>();
private static readonly IConnectionManager s_connectionManager = new ConnectionManagerV1();
private static readonly Object s_connectionManagerInstanceLock = new Object();
private static IConnectionManager s_connectionManager;
private static IConnectionManager ConnectionManager
{
get
{
if (s_connectionManager != null)
return s_connectionManager;
lock (s_connectionManagerInstanceLock)
{
s_connectionManager = new ConnectionManagerV1(); // old implementation of the pool as a default
}
return s_connectionManager;
}
}

internal static SFSession GetSession(string connectionString, SecureString password)
{
s_logger.Debug("SnowflakeDbConnectionPool::GetSession");
return s_connectionManager.GetSession(connectionString, password);
return ConnectionManager.GetSession(connectionString, password);
}

internal static Task<SFSession> GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken)
{
s_logger.Debug("SnowflakeDbConnectionPool::GetSessionAsync");
return s_connectionManager.GetSessionAsync(connectionString, password, cancellationToken);
return ConnectionManager.GetSessionAsync(connectionString, password, cancellationToken);
}

internal static bool AddSession(SFSession session)
{
s_logger.Debug("SnowflakeDbConnectionPool::AddSession");
return s_connectionManager.AddSession(session);
return ConnectionManager.AddSession(session);
}

public static void ClearAllPools()
{
s_logger.Debug("SnowflakeDbConnectionPool::ClearAllPools");
s_connectionManager.ClearAllPools();
ConnectionManager.ClearAllPools();
}

public static void SetMaxPoolSize(int maxPoolSize)
{
s_logger.Debug("SnowflakeDbConnectionPool::SetMaxPoolSize");
s_connectionManager.SetMaxPoolSize(maxPoolSize);
ConnectionManager.SetMaxPoolSize(maxPoolSize);
}

public static int GetMaxPoolSize()
{
s_logger.Debug("SnowflakeDbConnectionPool::GetMaxPoolSize");
return s_connectionManager.GetMaxPoolSize();
return ConnectionManager.GetMaxPoolSize();
}

public static void SetTimeout(long connectionTimeout)
{
s_logger.Debug("SnowflakeDbConnectionPool::SetTimeout");
s_connectionManager.SetTimeout(connectionTimeout);
ConnectionManager.SetTimeout(connectionTimeout);
}

public static long GetTimeout()
{
s_logger.Debug("SnowflakeDbConnectionPool::GetTimeout");
return s_connectionManager.GetTimeout();
return ConnectionManager.GetTimeout();
}

public static int GetCurrentPoolSize()
{
s_logger.Debug("SnowflakeDbConnectionPool::GetCurrentPoolSize");
return s_connectionManager.GetCurrentPoolSize();
return ConnectionManager.GetCurrentPoolSize();
}

public static bool SetPooling(bool isEnable)
{
s_logger.Debug("SnowflakeDbConnectionPool::SetPooling");
return s_connectionManager.SetPooling(isEnable);
return ConnectionManager.SetPooling(isEnable);
}

public static bool GetPooling()
{
s_logger.Debug("SnowflakeDbConnectionPool::GetPooling");
return s_connectionManager.GetPooling();
return ConnectionManager.GetPooling();
}

internal static void SwapVersion()
{
lock (s_connectionManagerInstanceLock)
{
if (ConnectionManager is ConnectionManagerV1)
{
s_connectionManager.ClearAllPools();
s_connectionManager = new ConnectionManagerV2();
}
if (ConnectionManager is ConnectionManagerV2)
{
s_connectionManager.ClearAllPools();
s_connectionManager = new ConnectionManagerV1();
}
}

Check warning on line 114 in Snowflake.Data/Client/SnowflakeDbConnectionPool.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Client/SnowflakeDbConnectionPool.cs#L101-L114

Added lines #L101 - L114 were not covered by tests
}
}
}
6 changes: 5 additions & 1 deletion Snowflake.Data/Core/Session/ConnectionManagerV1.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved.
*/

using System.Security;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -6,7 +10,7 @@ namespace Snowflake.Data.Core.Session
{
internal sealed class ConnectionManagerV1 : IConnectionManager
{
private readonly SessionPool _sessionPool = new SessionPool();
private readonly SessionPool _sessionPool = SessionPool.CreateSessionPoolV1();
public SFSession GetSession(string connectionString, SecureString password) => _sessionPool.GetSession(connectionString, password);
public Task<SFSession> GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken)
=> _sessionPool.GetSessionAsync(connectionString, password, cancellationToken);
Expand Down
107 changes: 107 additions & 0 deletions Snowflake.Data/Core/Session/ConnectionManagerV2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
*/

using System;
using System.Collections.Generic;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Snowflake.Data.Log;

namespace Snowflake.Data.Core.Session
{
internal sealed class ConnectionManagerV2 : IConnectionManager
{
private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger<ConnectionManagerV2>();
private static readonly Object s_poolsLock = new Object();

Check warning on line 17 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L16-L17

Added lines #L16 - L17 were not covered by tests
private readonly Dictionary<string, SessionPool> _pools;

internal ConnectionManagerV2()
{
lock (s_poolsLock)
{
_pools = new Dictionary<string, SessionPool>();
}
}

Check warning on line 26 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L20-L26

Added lines #L20 - L26 were not covered by tests

public SFSession GetSession(string connectionString, SecureString password)
=> GetPool(connectionString, password).GetSession();

Check warning on line 29 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L29

Added line #L29 was not covered by tests

public Task<SFSession> GetSessionAsync(string connectionString, SecureString password, CancellationToken cancellationToken)
=> GetPool(connectionString, password).GetSessionAsync(cancellationToken);

Check warning on line 32 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L32

Added line #L32 was not covered by tests

public bool AddSession(SFSession session)
=> GetPool(session.ConnectionString, session.Password).AddSession(session);

Check warning on line 35 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L35

Added line #L35 was not covered by tests

public void ClearAllPools()
{
foreach (var sessionPool in _pools.Values)
{
sessionPool.ClearAllPools();
}
}

Check warning on line 43 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L38-L43

Added lines #L38 - L43 were not covered by tests

public void SetMaxPoolSize(int maxPoolSize)
{
foreach (var pool in _pools.Values)
{
pool.SetMaxPoolSize(maxPoolSize);
}
}

Check warning on line 51 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L46-L51

Added lines #L46 - L51 were not covered by tests

public int GetMaxPoolSize() => throw ApiNotSupportedException();

Check warning on line 53 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L53

Added line #L53 was not covered by tests

public void SetTimeout(long connectionTimeout)
{
foreach (var pool in _pools.Values)
{
pool.SetTimeout(connectionTimeout);
}
}

Check warning on line 61 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L56-L61

Added lines #L56 - L61 were not covered by tests

public long GetTimeout() => throw ApiNotSupportedException();

Check warning on line 63 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L63

Added line #L63 was not covered by tests

public int GetCurrentPoolSize() => throw ApiNotSupportedException();

Check warning on line 65 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L65

Added line #L65 was not covered by tests

public bool SetPooling(bool poolingEnabled)
{
bool switched = true;
foreach (var pool in _pools.Values)
{
if (!pool.SetPooling(poolingEnabled))
switched = false;
}
return switched;
}

Check warning on line 76 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L68-L76

Added lines #L68 - L76 were not covered by tests

public bool GetPooling() => throw ApiNotSupportedException();

Check warning on line 78 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L78

Added line #L78 was not covered by tests

private NotSupportedException ApiNotSupportedException()
{
var message = "Pool settings are controlled with connection string parameters or from a Session Pool object";
s_logger.Error(message);
return new NotSupportedException(message);
}

Check warning on line 85 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L81-L85

Added lines #L81 - L85 were not covered by tests

internal SessionPool GetPool(string connectionString, SecureString password)
{
var poolKey = GetPoolKey(connectionString);

Check warning on line 89 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L88-L89

Added lines #L88 - L89 were not covered by tests

if (_pools.TryGetValue(poolKey, out var item))
return item;
lock (s_poolsLock)
{
var pool = SessionPool.CreateSessionPoolV2(connectionString, password);
_pools.Add(poolKey, pool);
return pool;

Check warning on line 97 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L91-L97

Added lines #L91 - L97 were not covered by tests
}
}

Check warning on line 99 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L99

Added line #L99 was not covered by tests

// TODO: SNOW-937188
private string GetPoolKey(string connectionString)
{
return connectionString;
}

Check warning on line 105 in Snowflake.Data/Core/Session/ConnectionManagerV2.cs

View check run for this annotation

Codecov / codecov/patch

Snowflake.Data/Core/Session/ConnectionManagerV2.cs#L103-L105

Added lines #L103 - L105 were not covered by tests
}
}
11 changes: 6 additions & 5 deletions Snowflake.Data/Core/Session/SFSession.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved.
* Copyright (c) 2012-2023 Snowflake Computing Inc. All rights reserved.
*/

using System;
Expand All @@ -15,7 +15,6 @@
using System.Threading.Tasks;
using System.Net.Http;
using System.Text.RegularExpressions;
using Snowflake.Data.Configuration;

namespace Snowflake.Data.Core
{
Expand Down Expand Up @@ -69,7 +68,8 @@ public class SFSession
private readonly EasyLoggingStarter _easyLoggingStarter = EasyLoggingStarter.Instance;

private long _startTime = 0;
internal string connStr = null;
internal readonly string ConnectionString;
internal readonly SecureString Password;

private QueryContextCache _queryContextCache = new QueryContextCache(_defaultQueryContextCacheSize);

Expand Down Expand Up @@ -145,8 +145,9 @@ internal SFSession(
EasyLoggingStarter easyLoggingStarter)
{
_easyLoggingStarter = easyLoggingStarter;
connStr = connectionString;
properties = SFSessionProperties.parseConnectionString(connectionString, password);
ConnectionString = connectionString;
Password = password;
properties = SFSessionProperties.parseConnectionString(ConnectionString, Password);
_disableQueryContextCache = bool.Parse(properties[SFSessionProperty.DISABLEQUERYCONTEXTCACHE]);
ValidateApplicationName(properties);
try
Expand Down
Loading

0 comments on commit 73bb45c

Please sign in to comment.