Module embedded_redis::network

source ·
Expand description

§Connection and regular Client logic

§Connection handling

Redis connection is managed by ConnectionHandler. Both RESP2 and RESP3 protocol are supported.

Creating a new connection requires the following two things:

let mut network_stack = Stack::default();
let clock = StandardClock::default();

// RESP2 protocol
let mut connection_handler = ConnectionHandler::resp2(SocketAddr::from_str("127.0.0.1:6379").unwrap());
let _client = connection_handler.connect(&mut network_stack, Some(&clock)).unwrap();

// RESP3 protocol
let mut connection_handler = ConnectionHandler::resp3(SocketAddr::from_str("127.0.0.1:6379").unwrap());
let _client = connection_handler.connect(&mut network_stack, Some(&clock)).unwrap();

ConnectionHandler is caching the connection, so later recreation of new Clients is cheap.

§Authentication

Authentication is done in the following way:

// Password only authentication
let mut connection_handler = ConnectionHandler::resp2(server_address);
connection_handler.auth(Credentials::password_only("secret123!"));


// ACL based authentication
let mut connection_handler = ConnectionHandler::resp2(server_address);
connection_handler.auth(Credentials::acl("user01", "secret123!"));

§Timeout

The client includes a timeout mechanism. This allows setting a time limit for responses from the Redis server:

let mut connection_handler = ConnectionHandler::resp2(server_address);
connection_handler.timeout(500_000.microseconds());

§Ping

Optionally, the PING command can also be used to test the connection. PING is then used every time connect() is called after the socket has been cached.

It is recommended to use this option only if a Timeout is configured.

let mut connection_handler = ConnectionHandler::resp2(server_address);
connection_handler.timeout(500_000.microseconds());
connection_handler.use_ping();

§Memory optimization

The following parameters can be used to optimize memory usage respectively to improve heap allocation. The right parameters can also protect against DOS scenarios, when the received data can potentially exceed the memory resources. See MemoryParameters for more details.

let mut connection_handler = ConnectionHandler::resp3(server_address);

connection_handler.memory(MemoryParameters {
    buffer_size: 512,
    frame_capacity: 4,
    memory_limit: Some(4096)
});

§Concurrency

While the Client is not Send, the connection handler is. The handler is designed with the approach that the creation of new clients is cheap. Thus, the use of short-lived clients in concurrent applications is not a problem.

§Non-blocking response management

Redis server responses are managed as Future. This allows executing multiple commands non-blocking simultaneously* and handle responses in any order at any point in time:

let future1 = client.set("key", "value").unwrap();
let future2 = client.set("other", "key").unwrap();

let _ = future2.wait();
let _ = future1.wait();

§Ready

In order to check whether a future is ready, (the corresponding response has arrived), the method ready() can be used. If ready() returns true, then next call to wait() is not expected to block.

let mut future = client.set("key", "value").unwrap();

if future.ready() {
   let _ = future.wait();
}

§Response type

Response type dependents on executed command abstractions, e.g. GetResponse in case of GET command.

§Timeout error

In the event of a timeout error, all remaining futures will be invalidated, as the assignment of responses can no longer be guaranteed. In case of a invalidated future InvalidFuture error is returned when calling wait().

§Clean state

If the futures are not waited for, it is recommended to call the close method before client goes out-of-scope. This ensures a clean state if a new client is later created with the same network connection.

let _ = client.set("key", "value");
client.close();

Structs§

Enums§