#postgresql #sql #async

kpgres

A native, asynchronous PostgreSQL client for Kayrx

1 unstable release

0.5.0 Jan 30, 2020

#111 in #postgres

MIT license

210KB
4.5K SLoC

kpgres

The native, asynchronous PostgreSQL client for Kayrx


lib.rs:

An asynchronous, pipelined, PostgreSQL client.

Behavior

Calling a method like Client::query on its own does nothing. The associated request is not sent to the database until the future returned by the method is first polled. Requests are executed in the order that they are first polled, not in the order that their futures are created.

Pipelining

The client supports pipelined requests. Pipelining can improve performance in use cases in which multiple, independent queries need to be executed. In a traditional workflow, each query is sent to the server after the previous query completes. In contrast, pipelining allows the client to send all of the queries to the server up front, minimizing time spent by one side waiting for the other to finish sending data:

            Sequential                              Pipelined
| Client         | Server          |    | Client         | Server          |
|----------------|-----------------|    |----------------|-----------------|
| send query 1   |                 |    | send query 1   |                 |
|                | process query 1 |    | send query 2   | process query 1 |
| receive rows 1 |                 |    | send query 3   | process query 2 |
| send query 2   |                 |    | receive rows 1 | process query 3 |
|                | process query 2 |    | receive rows 2 |                 |
| receive rows 2 |                 |    | receive rows 3 |                 |
| send query 3   |                 |
|                | process query 3 |
| receive rows 3 |                 |

In both cases, the PostgreSQL server is executing the queries sequentially - pipelining just allows both sides of the connection to work concurrently when possible.

Pipelining happens automatically when futures are polled concurrently (for example, by using the futures join combinator):

use futures::future;
use std::future::Future;
use kpgres::{Client, Error, Statement};

async fn pipelined_prepare(
    client: &Client,
) -> Result<(Statement, Statement), Error>
{
    future::try_join(
        client.prepare("SELECT * FROM foo"),
        client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)")
    ).await
}

SSL/TLS support

TLS support is implemented via external libraries. Client::connect and Config::connect take a TLS implementation as an argument. The NoTls type in this crate can be used when TLS is not required. Otherwise, the postgres-openssl and postgres-native-tls crates provide implementations backed by the openssl and native-tls crates, respectively.

Dependencies

~36MB
~791K SLoC