blob: 8ed3cb32cbdbc3a4e09bb3bccf734f4071f59cb9 [file]
/**
* SessionPool Example
*
* This example demonstrates how to use SessionPool for efficient connection
* management in high-concurrency scenarios, including explicit session management.
*/
import { SessionPool, PoolConfigBuilder, TreeTablet, TSDataType } from "../src";
async function main() {
console.log("=== SessionPool Example ===\n");
// Method 1: Traditional constructor (backward compatible)
console.log("Creating session pool using traditional constructor...");
const pool1 = new SessionPool("localhost", 6667, {
username: "root",
password: "root",
maxPoolSize: 10,
minPoolSize: 2,
maxIdleTime: 60000,
waitTimeout: 60000,
});
// Method 2: Using Builder pattern (recommended)
console.log("Creating session pool using Builder pattern...");
const pool2 = new SessionPool(
new PoolConfigBuilder()
.host("localhost")
.port(6667)
.username("root")
.password("root")
.maxPoolSize(10)
.minPoolSize(2)
.maxIdleTime(60000)
.waitTimeout(60000)
.build(),
);
// For demo purposes, we'll use pool1
const pool = pool1;
try {
// Initialize the pool
console.log("\nInitializing session pool...");
await pool.init();
console.log("Pool initialized with", pool.getPoolSize(), "connections");
// Create database
console.log("\nCreating database...");
await pool.executeNonQueryStatement("CREATE DATABASE root.pool_example");
// Create timeseries
console.log("Creating timeseries...");
await pool.executeNonQueryStatement(
"CREATE TIMESERIES root.pool_example.sensor1.value WITH DATATYPE=FLOAT",
);
// Approach 1: Using pool methods directly (automatic session management)
console.log("\n--- Approach 1: Automatic session management ---");
console.log("Executing concurrent queries...");
const promises = [];
for (let i = 0; i < 20; i++) {
promises.push(
pool.executeQueryStatement("SHOW DATABASES").then(async (dataSet) => {
let count = 0;
while (await dataSet.hasNext()) {
dataSet.next();
count++;
}
await dataSet.close();
console.log(`Query ${i + 1} completed with ${count} rows`);
}),
);
}
await Promise.all(promises);
console.log("All concurrent queries completed");
// Approach 2: Explicit session management (new API)
console.log("\n--- Approach 2: Explicit session management ---");
console.log("Getting a session from the pool...");
const session = await pool.getSession();
try {
console.log("Executing operations with explicit session...");
// Insert data using TreeTablet class with addRow
const tablet = new TreeTablet(
"root.pool_example.sensor1",
["value"],
[TSDataType.FLOAT]
);
tablet.addRow(Date.now(), [42.5]);
tablet.addRow(Date.now() + 1000, [43.0]);
await session.insertTablet(tablet);
console.log("Tree tablet data inserted via explicit session");
// Query data
const dataSet = await session.executeQueryStatement(
"SELECT * FROM root.pool_example.sensor1",
);
let rowCount = 0;
while (await dataSet.hasNext()) {
dataSet.next();
rowCount++;
}
await dataSet.close();
console.log("Query result:", rowCount, "rows");
} finally {
// Always release the session back to the pool
pool.releaseSession(session);
console.log("Session released back to the pool");
}
// Check pool statistics
console.log("\nPool statistics:");
console.log("Total connections:", pool.getPoolSize());
console.log("Available connections:", pool.getAvailableSize());
console.log("In-use connections:", pool.getInUseSize());
// Enhanced metrics
console.log("\nEnhanced pool metrics:");
console.log("Total (new API):", pool.totalCount);
console.log("Idle (new API):", pool.idleCount);
console.log("Active (new API):", pool.activeCount);
console.log("Waiting requests:", pool.waitingCount);
// Comprehensive statistics
const stats = pool.getPoolStats();
console.log("\nComprehensive stats:", stats);
// Approach 3: Concurrent batch insertion (NEW API)
console.log("\n--- Approach 3: Concurrent batch insertion (insertTabletsParallel) ---");
const tablets = [];
const batchTime = Date.now();
for (let i = 0; i < 20; i++) {
tablets.push({
deviceId: `root.pool_example.batch_sensor${i}`,
measurements: ["value"],
dataTypes: [TSDataType.FLOAT],
timestamps: [batchTime + i * 1000],
values: [[100.0 + i]],
});
}
console.log(`Inserting ${tablets.length} tablets concurrently...`);
const startTime = Date.now();
await pool.insertTabletsParallel(tablets, { concurrency: 5 });
const elapsed = Date.now() - startTime;
console.log(`Inserted ${tablets.length} tablets in ${elapsed}ms (${(tablets.length * 1000 / elapsed).toFixed(2)} tablets/sec)`);
// Approach 4: Generic parallel execution (NEW API)
console.log("\n--- Approach 4: Generic parallel execution (executeParallel) ---");
const deviceNames = ["parallel_d1", "parallel_d2", "parallel_d3", "parallel_d4"];
console.log(`Creating ${deviceNames.length} timeseries in parallel...`);
const results = await pool.executeParallel(
deviceNames,
async (session, deviceName) => {
try {
await session.executeNonQueryStatement(
`CREATE TIMESERIES root.pool_example.${deviceName}.value WITH DATATYPE=FLOAT`
);
} catch {
// Ignore if already exists
}
return `Created ${deviceName}`;
},
{ concurrency: 4 }
);
console.log("Results:", results);
} catch (error) {
console.error("Error:", error);
} finally {
// Close the pool
console.log("\nClosing session pool...");
await pool.close();
console.log("Pool closed");
}
}
main().catch(console.error);