-
Notifications
You must be signed in to change notification settings - Fork 0
Add PostgreSQL connection pooling comparison scripts and functionality #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
goh-chunlin
merged 32 commits into
main
from
74_postgresql-connection-pooling-simulation
Apr 11, 2026
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
cf96ffa
Add PostgreSQL connection pooling comparison scripts and functionality
goh-chunlin aba2547
fix(AzureDbBehavior): adjust PostgreSQL connection overhead handling …
goh-chunlin 04991c6
refactor(ConnectionPool): simplify constructor by removing pooling mo…
goh-chunlin 0a282e6
feat(AzureDbBehavior): implement deferred connection acquisition for …
goh-chunlin 6350fb2
fix(ConnectionPool): validate pool size for non-direct pooling modes …
goh-chunlin 02c2776
feat(AzurePgsqlPoolingScenario): implement random session hold time f…
goh-chunlin a4a9c7e
feat(AzureDbBehavior): implement simulated connection wait time for P…
goh-chunlin 7238f53
feat(AzurePgsqlPoolingScenario): add validation for positive pool siz…
goh-chunlin 3214c02
feat(pooling-scripts): enhance precision in latency calculations usin…
goh-chunlin b9e3c82
feat(ConnectionReleaseEvent): add event for delayed connection releas…
goh-chunlin 922e2e7
fix(pool-size-comparison): handle errors during pool size execution a…
goh-chunlin af01fa1
feat(AzureDbBehavior): update connection acquisition logic to bypass …
goh-chunlin bd9adf3
feat(AzureDbBehavior): refine burn logic and service time estimation …
goh-chunlin d062de6
fix(azure-pgsql-pooling): improve pool size validation logic for sess…
goh-chunlin 0923156
feat: ensure script directory resolution for relative paths in simula…
goh-chunlin d027e79
feat(ConnectionPool): update acquisition logic to implement spillover…
goh-chunlin 9d28ba2
feat(AzureDbBehavior): enhance connection acquisition logic for pooli…
goh-chunlin 550a942
refactor(ConnectionPool): update documentation to clarify spillover s…
goh-chunlin 930ecea
feat(pooling-comparison): merge latency and credits data by query ind…
goh-chunlin fda6b66
refactor(pool-size-comparison): remove unnecessary sorting of latenci…
goh-chunlin 4d33ec2
refactor(pooling-comparison): update latency calculations to use medi…
goh-chunlin 0b950ba
feat(pool-size-comparison): update latency calculations to use median…
goh-chunlin 11e1262
refactor(pool-size-comparison): update threshold for optimal pool siz…
goh-chunlin e051979
fix(pooling-comparison): ensure latency and credits values are treate…
goh-chunlin 2de54b9
refactor(pooling-simulation): update comments to clarify spillover mo…
goh-chunlin 83071ee
refactor(scenarios): update log messages to clarify CSV output location
goh-chunlin 1514f29
refactor(pooling-comparison): update scripts to generate median laten…
goh-chunlin 92d8156
refactor(azure-db-registry): remove redundant comments from Burstable…
goh-chunlin 859324a
refactor(azure-db-registry): enhance comments for BurstableInstanceSp…
goh-chunlin f1a755e
refactor(pooling-comparison): check for required CSV files before gen…
goh-chunlin 7aea02b
refactor(pool-size-comparison): add checks for summary data and optim…
goh-chunlin 55992fc
refactor(pool-size-comparison): improve checks for summary data avail…
goh-chunlin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| namespace SimNextgenApp.Demo.AzureDbSample; | ||
|
|
||
| /// <summary> | ||
| /// Simulates a connection pool for PostgreSQL with SPILLOVER semantics. | ||
| /// When the pool is exhausted, callers can open direct connections to the database, | ||
| /// temporarily exceeding the pool size (unlike true hard-limit pools that queue requests). | ||
| /// Connection acquisition happens when server starts processing (deferred acquisition). | ||
| /// </summary> | ||
| internal class ConnectionPool | ||
| { | ||
| private readonly int _poolSize; | ||
| private readonly HashSet<string> _availableConnections; | ||
| private readonly Dictionary<string, string> _assignedConnections; // Query → Connection | ||
|
|
||
| public ConnectionPool(int poolSize) | ||
| { | ||
| if (poolSize <= 0) | ||
| { | ||
| throw new ArgumentException($"Pool size must be positive (got {poolSize}). Use Direct mode if you don't want pooling.", nameof(poolSize)); | ||
| } | ||
|
|
||
| _poolSize = poolSize; | ||
| _availableConnections = new HashSet<string>(); | ||
| _assignedConnections = new Dictionary<string, string>(); | ||
|
|
||
| // Initialize pool with connection IDs | ||
| for (int i = 0; i < poolSize; i++) | ||
| { | ||
| _availableConnections.Add($"conn_{i}"); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Attempts to acquire a connection from the pool. | ||
| /// Returns connection ID if successful, null if pool is exhausted. | ||
| /// | ||
| /// SPILLOVER MODEL: When pool is exhausted (returns null), caller opens | ||
| /// a new direct connection to the database, bypassing the pool and paying | ||
| /// full connection overhead (50ms). This models scenarios where applications | ||
| /// fall back to direct connections when the pool is saturated, allowing | ||
| /// temporary exceedance of the pool size under load spikes. | ||
| /// | ||
| /// Note: This differs from PgBouncer's default queue-and-wait behavior. | ||
| /// Use this model to simulate spillover capacity in high-traffic scenarios. | ||
| /// | ||
| /// Called at SERVICE START (deferred acquisition), not at load creation. | ||
| /// Requests naturally queue in SimQueue before reaching this point. | ||
|
goh-chunlin marked this conversation as resolved.
|
||
| /// </summary> | ||
| public string? AcquireConnection(string queryId) | ||
| { | ||
| if (_availableConnections.Count == 0) | ||
| { | ||
| // Pool exhausted - caller opens direct connection bypassing pool (spillover model) | ||
| return null; | ||
| } | ||
|
goh-chunlin marked this conversation as resolved.
|
||
|
|
||
| // Get first available connection | ||
| string connectionId = _availableConnections.First(); | ||
| _availableConnections.Remove(connectionId); | ||
| _assignedConnections[queryId] = connectionId; | ||
|
|
||
| return connectionId; | ||
| } | ||
|
goh-chunlin marked this conversation as resolved.
|
||
|
|
||
| /// <summary> | ||
| /// Releases a connection back to the pool after query completion. | ||
| /// </summary> | ||
| public void ReleaseConnection(string queryId) | ||
| { | ||
| if (_assignedConnections.TryGetValue(queryId, out string? connectionId)) | ||
| { | ||
| _assignedConnections.Remove(queryId); | ||
| _availableConnections.Add(connectionId); | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Total capacity of the connection pool. | ||
| /// </summary> | ||
| public int Capacity => _poolSize; | ||
|
|
||
| /// <summary> | ||
| /// Number of available connections in the pool. | ||
| /// </summary> | ||
| public int AvailableCount => _availableConnections.Count; | ||
|
|
||
| /// <summary> | ||
| /// Number of connections currently in use. | ||
| /// </summary> | ||
| public int InUseCount => _assignedConnections.Count; | ||
|
|
||
| /// <summary> | ||
| /// Indicates whether the pool is fully exhausted (no available connections). | ||
| /// </summary> | ||
| public bool IsExhausted => _availableConnections.Count == 0; | ||
| } | ||
26 changes: 26 additions & 0 deletions
26
SimNextgenApp.Demo/AzureDbSample/ConnectionReleaseEvent.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| using SimNextgenApp.Core; | ||
| using SimNextgenApp.Events; | ||
|
|
||
| namespace SimNextgenApp.Demo.AzureDbSample; | ||
|
|
||
| /// <summary> | ||
| /// Event for delayed connection release in session pooling mode. | ||
| /// Simulates client holding connection between queries in a session. | ||
| /// </summary> | ||
| internal class ConnectionReleaseEvent : AbstractEvent | ||
| { | ||
| private readonly ConnectionPool _pool; | ||
| private readonly string _queryId; | ||
|
|
||
| public ConnectionReleaseEvent(ConnectionPool pool, string queryId) | ||
| { | ||
| _pool = pool; | ||
| _queryId = queryId; | ||
| } | ||
|
|
||
| public override void Execute(IRunContext context) | ||
| { | ||
| // Release connection back to pool after session hold time | ||
| _pool.ReleaseConnection(_queryId); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| using SimNextgenApp.Demo.CustomModels; | ||
|
|
||
| namespace SimNextgenApp.Demo.AzureDbSample; | ||
|
|
||
| /// <summary> | ||
| /// Represents a PostgreSQL query with connection pooling metadata. | ||
| /// Used to simulate PgBouncer-style connection pooling overhead. | ||
| /// </summary> | ||
| internal class PostgresQuery : MyLoad | ||
| { | ||
| /// <summary> | ||
| /// Indicates whether this query requires a new connection to be established. | ||
| /// True = new connection (50ms overhead), False = reused connection | ||
| /// </summary> | ||
| public bool IsNewConnection { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// The connection ID assigned to this query (for tracking pool usage). | ||
| /// Null when using deferred acquisition (assigned at service start). | ||
| /// </summary> | ||
| public string? ConnectionId { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// The pooling mode used for this query. | ||
| /// </summary> | ||
| public PoolingMode PoolMode { get; set; } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// PostgreSQL connection pooling modes (PgBouncer-style). | ||
| /// </summary> | ||
| internal enum PoolingMode | ||
| { | ||
| /// <summary> | ||
| /// Direct mode: New connection per query (50ms overhead every query). | ||
| /// </summary> | ||
| Direct, | ||
|
|
||
| /// <summary> | ||
| /// Session pooling: Connection held for session, reused with no overhead. | ||
| /// Best for most workloads. | ||
| /// </summary> | ||
| SessionPooling, | ||
|
|
||
| /// <summary> | ||
| /// Transaction pooling: Connection released after transaction with state reset. | ||
| /// Adds 8ms DISCARD ALL overhead per query. | ||
| /// </summary> | ||
| TransactionPooling | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.