-
Notifications
You must be signed in to change notification settings - Fork 3
Mmo30/new readme #69
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
Open
marco3479
wants to merge
12
commits into
master
Choose a base branch
from
mmo30/newREADME
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Mmo30/new readme #69
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
83a187d
Updated `package.json` minimally
marco3479 9ffae27
Added initial draft for README.md
marco3479 e638249
Broke down documentation into sections
marco3479 dbf5dc8
Improved docs
marco3479 d27d981
Added Retry Operations sections
marco3479 7688c1f
Replaced README with README2
marco3479 c791edb
Delete doc/README.md
marco3479 fdc5f9b
Added details
marco3479 c5a36ca
Addressed some PR comments
marco3479 53380df
Resolved review comments
marco3479 95275cf
Merge branch 'master' into mmo30/newREADME
marco3479 03f96fd
Minor Best Practices section Edit
marco3479 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,3 +9,6 @@ vol2/ | |
|
||
build/ | ||
node_modules/ | ||
|
||
test/t.js | ||
crash.log |
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,59 @@ | ||
|
||
# Best Practices | ||
|
||
## Single Connection vs Connection Pool | ||
|
||
While connection pooling offers advantages in managing multiple concurrent connections efficiently, a single connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. A single connection should result in quicker response times and is a more straightforward approach in applications with | ||
|
||
- Low to moderate traffic | ||
- Relatively stable workloads | ||
- Required strict control over transactions | ||
- Required strict control over isolation levels | ||
|
||
However, it's crucial to acknowledge that this approach might not be suitable for high-traffic applications where connection pooling shines by distributing the load and enhancing scalability. | ||
|
||
The decision between a single connection and a connection pool should always be context-dependent, carefully considering factors such as expected traffic, workload volatility, and performance requirements. | ||
|
||
## Type Safety | ||
|
||
The `node-nuodb` driver supports `try/catch`, `callback`, and `Promise` semantics. You should put guard rails that verify the availability of data and catching of any errors that could arise. For tighter type safety, you can deal with error catching at the operation level, rather than catching an errors of any operation within a block. | ||
|
||
Any `try` `catch` block in which **NuoDB** resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. | ||
|
||
## Retrying Operations | ||
|
||
Under critical operations, it is recommended to retry operations were they to fail. You could catch the exception, clean-up any operations, and retry the operations. To allow some time margin, increase the time between retries. Here is a retry example: | ||
|
||
```js | ||
async function() { | ||
const driver = new Driver(); | ||
let connection = null; | ||
let results = null; | ||
let tries = 1; | ||
|
||
while (tries < 6) { | ||
|
||
await new Promise(resolve => setTimeout(async () => { | ||
try { | ||
connection = await driver.connect(config); | ||
results = await connection.execute("SELECT * FROM SYSTEM.NODE;"); | ||
const rows = await results.getRows(); | ||
// use rows | ||
|
||
} catch (err) { | ||
console.error(err); | ||
|
||
} finally { | ||
if (results != null) { | ||
results.close().catch(err => { console.error(err) }); | ||
} | ||
if (connection != null) { | ||
connection.close().catch(err => { console.error(err) }); | ||
} | ||
tries++; | ||
resolve(); | ||
} | ||
}, 1000 * tries)); | ||
} | ||
} | ||
``` |
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,149 @@ | ||
|
||
# Connection Pool | ||
|
||
The **NuoDB Node.js** driver comes with a built-in connection pool. A connection pool serves a critical role in optimizing the interaction between applications and databases. | ||
|
||
Unlike establishing an individual connection for each database interaction, a connection pool efficiently manages a reusable collection of established connections. This approach significantly reduces the overhead associated with repeatedly establishing and closing connections, resulting in improved performance and resource utilization. | ||
|
||
With a connection pool in place, the **NuoDB** driver can intelligently manage the lifecycle of connections, offering seamless access to the **NuoDB** database while effectively mitigating the potential for connection bottlenecks and latency. This allows developers to optimize their application's responsiveness and scalability while ensuring an efficient and streamlined interaction with the database. | ||
|
||
|
||
## Overview | ||
|
||
The lifecycle of a connection pool of the `node-nuodb` driver to a **NuoDB** database entails: | ||
|
||
- Initialization of the connection `Pool` | ||
- Request connections from the `pool` | ||
- Use the connections | ||
- Release each connection | ||
- Close the `pool` | ||
|
||
For simplicity the examples to follow will use `try/catch` semantics, although `Promise` semantics is also permitted. | ||
|
||
The following is a general example requesting 2 connections on the connection pool. You would in turn manage each connection as a [single connection](./SINGLE_CONNECTION.md#execute-sql). | ||
|
||
```js | ||
const connectionConfig = { | ||
database: `test`, | ||
password: "dba", | ||
user: "dba", | ||
port: "48004", | ||
schema: "USER" | ||
}; | ||
|
||
const poolConfig = { | ||
minAvailable: 10, | ||
connectionConfig, | ||
maxAge: 2000, | ||
checkTime: 10000, | ||
maxLimit: 12, | ||
connectionRetryLimit: 5, | ||
}; | ||
|
||
async function() { | ||
let pool = null; | ||
|
||
try { | ||
pool = new Pool(poolConfig); | ||
const conn1 = await pool.requestConnection(); | ||
const conn2 = await pool.requestConnection(); | ||
// use each connection | ||
|
||
await pool.releaseConnection(conn1); | ||
await pool.releaseConnection(conn2); | ||
|
||
} catch (err) {/* handle error */} | ||
|
||
finally { | ||
try { | ||
if (pool != null) { | ||
await pool.closePool() | ||
} | ||
} catch (err) {/* handle error */} | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Initialize Connection Pool | ||
|
||
To initialize a connection pool, you must provide a pool configuration. Please review the shape of the [pool configuration](#pool-configuration) to customize for specific needs. Note, you must specify the [connection configuration](./SINGLE_CONNECTION.md#connection-properties) as for a single connection. After a pool is created the user must initialize it using the `init()` method. This will populate the pool. The pool is unavailable until this completes. | ||
|
||
```js | ||
const poolConfig = { | ||
minAvailable: 10, | ||
connectionConfig, | ||
maxAge: 2000, | ||
checkTime: 10000, | ||
maxLimit: 12, | ||
connectionRetryLimit: 5, | ||
}; | ||
|
||
async function() { | ||
const pool = new Pool(poolConfig); | ||
await pool.init() | ||
} | ||
``` | ||
|
||
## Request Connections | ||
|
||
Once the pool has been successfully initialized it is ready for use. There are now free connections that can be requested for use. You can see the pool connections via `pool.all_connections` and `pool.free_connections`. | ||
|
||
```js | ||
const conn1 = await Pool.requestConnection(); | ||
``` | ||
|
||
You can request multiple connections this way. Each connection can then be used as a [single connection](./SINGLE_CONNECTION.md#execute-sql) would. | ||
|
||
## Release Connections | ||
|
||
Once the user has finished using a connection, it can be returned to the pool. You must release a single connection at a time. Don't forget to manage each single connection's lifecycle properly prior to requesting its release. | ||
|
||
```js | ||
await pool.releaseConnection(conn1) | ||
``` | ||
|
||
Connections that have been released back to the connection pool should not be used anymore. Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. | ||
|
||
## Pool Closure | ||
|
||
Once the pool has been finished being used, it should be shutdown. | ||
|
||
```js | ||
await pool.closePool() | ||
``` | ||
|
||
This will close all of the connections in the pool regardless of whether or not they are in use. | ||
|
||
Users cannot manually close connections provided by the pool, and calling `connection.close()` on a connection provided by the pool will have the same effect as calling `Pool.releaseConnection(connection)`. | ||
|
||
|
||
## Pool Configuration | ||
|
||
```js | ||
{ | ||
minAvailable: number, | ||
connectionConfig: ConnectionConfig, | ||
maxAge: number, | ||
checkTime: number, | ||
maxLimit: number, | ||
connectionRetryLimit: number, | ||
id: number, | ||
skipCheckLivelinessOnRelease: boolean, | ||
livelinessCheck: "query"|string | ||
}; | ||
``` | ||
|
||
Key | Value | ||
--- | --- | ||
**connectionConfig** | the configuration that will be used to create the connection in the pool, required argument. | ||
**minAvailable** | initial size of the pool and the number of connections the pool will aim to maintain, default of 10 is used if no argument is provided. | ||
**maxAge** | Amount of time from connection creation until it will age out, default of 300000ms (5 minutes) is used if no argument is provided. | ||
**checkTime** | how often the pool will run an internal liveliness check on free connections, default of 120000ms(2 minutes) is used if no argument is provided. If 0 is provided, the liveliness check will be disabled. | ||
**maxLimit** | hard cap on the amount of live connection the pool can maintain, default of 200 is used if no argument is provided. If 0, the pool will have no hard cap. | ||
**connectionRetryLimit** | amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. | ||
**id** | optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. | ||
**skipCheckLivelinessOnRelease** | turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. | ||
**livelinessCheck** | indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query is used to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. | ||
|
||
|
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if you request connection "from" or "on" a connection pool.