Skip to content

Commit

Permalink
docs: internal pool connection provider (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
joyc-bq authored Nov 7, 2024
1 parent bea5bf5 commit 58ccf39
Show file tree
Hide file tree
Showing 20 changed files with 591 additions and 43 deletions.
2 changes: 1 addition & 1 deletion common/lib/internal_pooled_connection_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export class InternalPooledConnectionProvider implements PooledConnectionProvide
}

getPoolKey(hostInfo: HostInfo, props: Map<string, any>) {
return this._poolMapping?.getKey(hostInfo, props) ?? WrapperProperties.USER.get(props);
return this._poolMapping?.getPoolKey(hostInfo, props) ?? WrapperProperties.USER.get(props);
}

logConnections() {
Expand Down
2 changes: 1 addition & 1 deletion common/lib/utils/internal_pool_mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
import { HostInfo } from "../host_info";

export interface InternalPoolMapping {
getKey(hostInfo: HostInfo, originalProps: Map<string, any>): string;
getPoolKey(hostInfo: HostInfo, originalProps: Map<string, any>): string;
}
10 changes: 7 additions & 3 deletions docs/using-the-nodejs-wrapper/ReaderSelectionStrategies.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

To balance connections to reader instances more evenly, different selection strategies can be used. The following table describes the currently available selection strategies and any relevant configuration parameters for each strategy.

| Reader Selection Strategy | Configuration Parameter | Description | Default Value |
| ------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `random` | This strategy does not have configuration parameters. | The random strategy is the default selection strategy. When switching to a reader connection, the reader instance will be chosen randomly from the available database instances. | N/A |
| Reader Selection Strategy | Configuration Parameter | Description | Default Value |
| ------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `random` | This strategy does not have configuration parameters. | The random strategy is the default selection strategy. When switching to a reader connection, the reader instance will be chosen randomly from the available database instances. | N/A |
| `leastConnections` | This strategy does not have configuration parameters. | The least connections strategy will select reader instances based on which database instance has the least number of currently active connections. Note that this strategy is only available when [internal connection pools](./using-plugins/UsingTheReadWriteSplittingPlugin.md#internal-connection-pooling) are enabled - if you set the connection property without enabling internal pools, an error will be thrown. | N/A |
| `roundRobin` | See the following rows for configuration parameters. | The round robin strategy will select a reader instance by taking turns with all available database instances in a cycle. A slight addition to the round robin strategy is the weighted round robin strategy, where more connections will be passed to reader instances based on user specified connection properties. | N/A |
| | `roundRobinHostWeightPairs` | This optional parameter value must be a `string` type comma separated list of database host-weight pairs in the format `<host>:<weight>`. The host represents the database instance name, and the weight represents how many connections should be directed to the host in one cycle through all available hosts. For example, the value `instance-1:1,instance-2:4` means that for every connection to `instance-1`, there will be four connections to `instance-2`. <br><br> **Note:** The `<weight>` value in the string must be an integer greater than or equal to 1. | `null` |
| | `roundRobinDefaultWeight` | This optional parameter value must be an integer value. This parameter represents the default weight for any hosts that have not been configured with the `roundRobinHostWeightPairs` parameter. For example, if a connection were already established and host weights were set with `roundRobinHostWeightPairs` but a new reader host was added to the database, the new reader host would use the default weight. <br><br> **Note:** This value must be an integer greater than or equal to 1. | `1` |
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The figure above provides a simplified overview of how the AWS Advanced NodeJS W

In this example, the application requests a connection using the Aurora DB cluster endpoint and is returned with a logical connection that is physically connected to the primary DB instance in the DB cluster, DB instance C. By design, details about which specific DB instance the physical connection is connected to have been abstracted away.

Over the course of the application's lifetime, it executes various statements against the logical connection. If DB instance C is stable and active, these statements succeed and the application continues as normal. If DB instance C experiences a failure, Aurora will initiate failover to promote a new primary DB instance. At the same time, the NodeJS Wrapper will intercept the related communication exception and kick off its own internal failover process.
Over the course of the application's lifetime, it executes various statements against the logical connection. If DB instance C is stable and active, these statements succeed and the application continues as normal. If DB instance C experiences a failure, Aurora will initiate failover to promote a new primary DB instance. At the same time, the NodeJS Wrapper will intercept the related communication error and kick off its own internal failover process.

If the primary DB instance has failed, the NodeJS Wrapper attempts to use its internal topology cache to temporarily connect to an active Aurora Replica. This Aurora Replica will be periodically queried for the DB cluster topology until the new primary DB instance is identified (DB instance A or B in this case). If the wrapper is unable to connect to an active Aurora Replica or the cluster is still being reconfigured, the wrapper will retry the connection until it is successful.

Expand Down Expand Up @@ -48,7 +48,7 @@ When connecting to Aurora clusters, the [`clusterInstanceHostPattern`](#failover

### FailoverFailedError

When the AWS NodeJS Wrapper throws a `FailoverFailedError`, the original connection has failed, and the AWS NodeJS Wrapper tried to failover to a new instance, but was unable to. There are various reasons this may happen: no nodes were available, a network failure occurred, and so on. In this scenario, please wait until the server is up or other problems are solved. (Exception will be thrown.)
When the AWS NodeJS Wrapper throws a `FailoverFailedError`, the original connection has failed, and the AWS NodeJS Wrapper tried to failover to a new instance, but was unable to. There are various reasons this may happen: no nodes were available, a network failure occurred, and so on. In this scenario, please wait until the server is up or other problems are solved. (Error will be thrown.)

### FailoverSuccessError

Expand All @@ -70,13 +70,14 @@ When the AWS Advanced NodeJS Wrapper throws a `TransactionResolutionUnknownError

#### Sample Code

[PostgreSQL Failover Sample Code](./../../examples/PgFailoverSample.java)
[PostgreSQL Failover Sample Code](../../../examples/aws_driver_example/aws_failover_postgresql_example.ts)
[MySQL Failover Sample Code](../../../examples/aws_driver_example/aws_failover_mysql_example.ts)

> [!WARNING]
>
> #### Warnings About Proper Usage of the AWS Advanced NodeJS Wrapper
>
> 1. Some users may wrap invocations against a Client object in a try-catch block or add a `.catch()` block to the invocation, and dispose of the Client object if an Error occurs. In this case, the application will lose the fast-failover functionality offered by the NodeJS Wrapper. When failover occurs, the NodeJS Wrapper internally establishes a ready-to-use connection inside the original Client object before throwing an exception to the user. If this Client object is disposed of, the newly established connection will be thrown away. The correct practice is to check the error type of the exception and reuse the Client object if the error code indicates successful failover. The [PostgreSQL Failover Sample Code](./../../examples/PgFailoverSample.java) demonstrates this practice. See the section about [Failover Errors](#failover-errors) for more details.
> 1. Some users may wrap invocations against a Client object in a try-catch block or add a `.catch()` block to the invocation, and dispose of the Client object if an Error occurs. In this case, the application will lose the fast-failover functionality offered by the NodeJS Wrapper. When failover occurs, the NodeJS Wrapper internally establishes a ready-to-use connection inside the original Client object before throwing an Error to the user. If this Client object is disposed of, the newly established connection will be thrown away. The correct practice is to check the error type of the Error and reuse the Client object if the error code indicates successful failover. The [PostgreSQL Failover Sample Code](./../../../examples/aws_driver_example/aws_failover_postgresql_example.ts) and [MySQL Failover Sample Code](./../../../examples/aws_driver_example/aws_failover_mysql_example.ts) demonstrates this practice. See the section about [Failover Errors](#failover-errors) for more details.
<br><br>

Expand Down
Loading

0 comments on commit 58ccf39

Please sign in to comment.