cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
cwist_redis.c File Reference

Minimal RESP2 Redis client with connection pooling. More...

#include <cwist/net/redis/cwist_redis.h>
#include "redis_frame_internal.h"
#include <cwist/core/mem/alloc.h>
#include <cwist/core/sstring/sstring.h>
#include <cwist/sys/err/cwist_err.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
Include dependency graph for cwist_redis.c:

Go to the source code of this file.

Macros

#define _POSIX_C_SOURCE   200809L
 
#define CWIST_REDIS_BUF_SIZE   65536
 
#define CWIST_REDIS_LINE_MAX   8192
 
#define CWIST_REDIS_MAX_BULK_BYTES   ((long long)(512 * 1024 * 1024))
 
#define CWIST_REDIS_MAX_REPLY_DEPTH   16
 
#define CWIST_REDIS_MAX_REPLY_ELEMENTS   (1 << 20)
 
#define CWIST_REDIS_TIMED_MAX_ARGC   ((size_t)1 << 20)
 
#define CWIST_REDIS_TIMED_MAX_FRAME   ((size_t)512 * 1024 * 1024)
 
#define CWIST_REDIS_TIMED_MAX_DEPTH   8
 
#define CWIST_REDIS_TIMED_MAX_NODES   ((size_t)65536)
 
#define CWIST_REDIS_TIMED_MAX_BULK   ((size_t)8 * 1024 * 1024)
 
#define CWIST_REDIS_TIMED_MAX_PAYLOAD   ((size_t)16 * 1024 * 1024)
 
#define CWIST_REDIS_NOSIGNAL   0
 

Typedefs

typedef struct redis_timed_parse redis_timed_parse
 

Functions

void cwist_redis_reply_free (cwist_redis_reply_t *reply)
 
cwist_error_t cwist_redis_command_argv_reply (cwist_redis_t *r, size_t argc, const void *const *argv, const size_t *argv_lens, cwist_redis_reply_t **reply)
 
cwist_redis_t * cwist_redis_connect (const char *host, int port)
 Open a TCP connection to a Redis server.
 
void cwist_redis_close (cwist_redis_t *r)
 Close a Redis connection.
 
cwist_error_t cwist_redis_command (cwist_redis_t *r, const char *cmd, char **out)
 Execute a raw Redis command and return the bulk reply.
 
cwist_error_t cwist_redis_command_argv (cwist_redis_t *r, size_t argc, const void *const *argv, const size_t *argv_lens, char **out, size_t *out_len)
 
cwist_error_t cwist_redis_auth (cwist_redis_t *r, const char *username, const char *password)
 
cwist_error_t cwist_redis_select (cwist_redis_t *r, unsigned int database)
 
cwist_error_t cwist_redis_get (cwist_redis_t *r, const char *key, char **out_value)
 Convenience commands.
 
cwist_error_t cwist_redis_set (cwist_redis_t *r, const char *key, const char *value)
 
cwist_error_t cwist_redis_setex (cwist_redis_t *r, const char *key, const char *value, int seconds)
 
cwist_error_t cwist_redis_del (cwist_redis_t *r, const char *key)
 
cwist_error_t cwist_redis_expire (cwist_redis_t *r, const char *key, int seconds)
 
cwist_error_t cwist_redis_publish (cwist_redis_t *r, const char *channel, const char *message)
 
cwist_error_t cwist_redis_subscribe (cwist_redis_t *r, const char **channels, cwist_redis_msg_cb cb, void *ctx)
 Subscribe to channels on a dedicated connection.
 
cwist_redis_pool_t * cwist_redis_pool_create (const char *host, int port, size_t max_conns)
 Create a Redis connection pool.
 
void cwist_redis_pool_destroy (cwist_redis_pool_t *pool)
 Destroy the pool and close all connections.
 
cwist_error_t cwist_redis_pool_get (cwist_redis_pool_t *pool, const char *key, char **out_value)
 Pooled convenience commands.
 
cwist_error_t cwist_redis_pool_set (cwist_redis_pool_t *pool, const char *key, const char *value)
 
cwist_error_t cwist_redis_pool_setex (cwist_redis_pool_t *pool, const char *key, const char *value, int seconds)
 
cwist_error_t cwist_redis_pool_del (cwist_redis_pool_t *pool, const char *key)
 
cwist_error_t cwist_redis_pool_publish (cwist_redis_pool_t *pool, const char *channel, const char *message)
 
cwist_error_t cwist_redis_pool_command_argv (cwist_redis_pool_t *pool, size_t argc, const void *const *argv, const size_t *argv_lens, char **out, size_t *out_len)
 
cwist_error_t cwist_redis_pool_command_argv_reply_timeout (cwist_redis_pool_t *pool, size_t argc, const void *const *argv, const size_t *argv_lens, unsigned timeout_ms, cwist_redis_reply_t **reply)
 Run one binary-safe pooled command under a single deadline.
 

Detailed Description

Minimal RESP2 Redis client with connection pooling.

Definition in file cwist_redis.c.

Macro Definition Documentation

◆ _POSIX_C_SOURCE

#define _POSIX_C_SOURCE   200809L

Definition at line 5 of file cwist_redis.c.

◆ CWIST_REDIS_BUF_SIZE

#define CWIST_REDIS_BUF_SIZE   65536

Definition at line 29 of file cwist_redis.c.

◆ CWIST_REDIS_LINE_MAX

#define CWIST_REDIS_LINE_MAX   8192

Definition at line 30 of file cwist_redis.c.

◆ CWIST_REDIS_MAX_BULK_BYTES

#define CWIST_REDIS_MAX_BULK_BYTES   ((long long)(512 * 1024 * 1024))

Definition at line 33 of file cwist_redis.c.

◆ CWIST_REDIS_MAX_REPLY_DEPTH

#define CWIST_REDIS_MAX_REPLY_DEPTH   16

Definition at line 36 of file cwist_redis.c.

◆ CWIST_REDIS_MAX_REPLY_ELEMENTS

#define CWIST_REDIS_MAX_REPLY_ELEMENTS   (1 << 20)

Definition at line 37 of file cwist_redis.c.

◆ CWIST_REDIS_NOSIGNAL

#define CWIST_REDIS_NOSIGNAL   0

Definition at line 53 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_ARGC

#define CWIST_REDIS_TIMED_MAX_ARGC   ((size_t)1 << 20)

Definition at line 42 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_BULK

#define CWIST_REDIS_TIMED_MAX_BULK   ((size_t)8 * 1024 * 1024)

Definition at line 46 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_DEPTH

#define CWIST_REDIS_TIMED_MAX_DEPTH   8

Definition at line 44 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_FRAME

#define CWIST_REDIS_TIMED_MAX_FRAME   ((size_t)512 * 1024 * 1024)

Definition at line 43 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_NODES

#define CWIST_REDIS_TIMED_MAX_NODES   ((size_t)65536)

Definition at line 45 of file cwist_redis.c.

◆ CWIST_REDIS_TIMED_MAX_PAYLOAD

#define CWIST_REDIS_TIMED_MAX_PAYLOAD   ((size_t)16 * 1024 * 1024)

Definition at line 47 of file cwist_redis.c.

Typedef Documentation

◆ redis_timed_parse

typedef struct redis_timed_parse redis_timed_parse

Function Documentation

◆ cwist_redis_auth()

cwist_error_t cwist_redis_auth ( cwist_redis_t *  r,
const char *  username,
const char *  password 
)

Authenticate against the server with ACL-style (username, password) or legacy (password-only) AUTH.

Parameters
rConnection handle.
usernameOptional ACL username; NULL selects password-only AUTH.
passwordPassword (required).
Returns
Error value indicating success or failure.

Definition at line 802 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command_argv(), and make_error().

◆ cwist_redis_close()

void cwist_redis_close ( cwist_redis_t *  r)

Close a Redis connection.

Close a connection and free the handle. Shuts the socket down first to wake a subscriber blocked in recv; this is the documented way to stop cwist_redis_subscribe(). Safe to call with NULL.

Definition at line 693 of file cwist_redis.c.

References cap, and cwist_free().

Referenced by cwist_redis_pool_create(), and cwist_redis_pool_destroy().

◆ cwist_redis_command()

cwist_error_t cwist_redis_command ( cwist_redis_t *  r,
const char *  cmd,
char **  out 
)

Execute a raw Redis command and return the bulk reply.

Send a raw RESP command string and return the flattened first-payload reply.

Parameters
rConnection handle.
cmdFull RESP-encoded command.
outOptional out: heap-allocated reply value (caller frees); freed internally when NULL.
Returns
Error value indicating success or failure.

Definition at line 740 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), and make_error().

Referenced by cwist_redis_del(), cwist_redis_expire(), cwist_redis_get(), cwist_redis_publish(), cwist_redis_set(), and cwist_redis_setex().

◆ cwist_redis_command_argv()

cwist_error_t cwist_redis_command_argv ( cwist_redis_t *  r,
size_t  argc,
const void *const *  argv,
const size_t *  argv_lens,
char **  out,
size_t *  out_len 
)

Execute a binary-safe Redis command expressed as explicit arguments. Reply strings are allocated with cwist_alloc() and may contain NUL bytes; use out_len to obtain their exact length.

Definition at line 764 of file cwist_redis.c.

References cap, count, CWIST_ERR_INT16, cwist_free(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_auth(), cwist_redis_pool_command_argv(), and cwist_redis_select().

◆ cwist_redis_command_argv_reply()

cwist_error_t cwist_redis_command_argv_reply ( cwist_redis_t *  r,
size_t  argc,
const void *const *  argv,
const size_t *  argv_lens,
cwist_redis_reply_t **  reply 
)

Execute a binary-safe command and return the full parsed reply tree.

Required for array-reply commands such as XREADGROUP/XAUTOCLAIM. On success *reply is set (free with cwist_redis_reply_free()); on a Redis '-' error the tree still describes the error but the returned error code is non-zero.

Definition at line 632 of file cwist_redis.c.

References cap, count, CWIST_ERR_INT16, cwist_redis_reply_free(), cwist_sstring_append_len(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

◆ cwist_redis_connect()

cwist_redis_t * cwist_redis_connect ( const char *  host,
int  port 
)

Open a TCP connection to a Redis server.

Open a TCP connection to a Redis server and allocate the client handle.

Parameters
hostServer host name or IPv4 address.
portServer port.
Returns
New connection handle on success, NULL on connection or allocation failure.

Definition at line 672 of file cwist_redis.c.

References cap, cwist_alloc(), and cwist_strdup().

Referenced by cwist_redis_pool_create().

◆ cwist_redis_del()

cwist_error_t cwist_redis_del ( cwist_redis_t *  r,
const char *  key 
)

Delete a key (DEL).

Parameters
rConnection handle.
keyKey to delete.
Returns
Error value indicating success or failure.

Definition at line 900 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_pool_del().

◆ cwist_redis_expire()

cwist_error_t cwist_redis_expire ( cwist_redis_t *  r,
const char *  key,
int  seconds 
)

Set a key's time-to-live in seconds (EXPIRE).

Parameters
rConnection handle.
keyKey to expire.
secondsTTL in seconds; must be positive.
Returns
Error value indicating success or failure.

Definition at line 919 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

◆ cwist_redis_get()

cwist_error_t cwist_redis_get ( cwist_redis_t *  r,
const char *  key,
char **  out_value 
)

Convenience commands.

Fetch the value of a key (GET).

Parameters
rConnection handle.
keyKey to read.
out_valueOut: heap-allocated value on success, NULL when the key is missing (caller frees).
Returns
Error value indicating success or failure.

Definition at line 840 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_pool_get().

◆ cwist_redis_pool_command_argv()

cwist_error_t cwist_redis_pool_command_argv ( cwist_redis_pool_t *  pool,
size_t  argc,
const void *const *  argv,
const size_t *  argv_lens,
char **  out,
size_t *  out_len 
)

Pool wrapper of cwist_redis_command_argv(): acquires a connection, runs the argv command, and releases the connection. See cwist_redis_command_argv() for parameter details.

Definition at line 1216 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_command_argv(), and make_error().

◆ cwist_redis_pool_command_argv_reply_timeout()

cwist_error_t cwist_redis_pool_command_argv_reply_timeout ( cwist_redis_pool_t *  pool,
size_t  argc,
const void *const *  argv,
const size_t *  argv_lens,
unsigned  timeout_ms,
cwist_redis_reply_t **  reply 
)

Run one binary-safe pooled command under a single deadline.

Deadline-bounded pooled command; see cwist_redis.h for the contract.

Definition at line 1444 of file cwist_redis.c.

References cap, cwist_free(), cwist_malloc(), and cwist_redis_reply_free().

◆ cwist_redis_pool_create()

cwist_redis_pool_t * cwist_redis_pool_create ( const char *  host,
int  port,
size_t  max_conns 
)

Create a Redis connection pool.

Create a connection pool with max_conns pre-opened connections.

Parameters
hostServer host name or IPv4 address.
portServer port.
max_connsNumber of connections to open; must be non-zero.
Returns
New pool handle on success, NULL on any connection or allocation failure (partial state is cleaned up).

Definition at line 1037 of file cwist_redis.c.

References cap, cwist_alloc(), cwist_alloc_array(), cwist_free(), cwist_redis_close(), cwist_redis_connect(), and cwist_strdup().

Referenced by cwist_app_use_redis().

◆ cwist_redis_pool_del()

cwist_error_t cwist_redis_pool_del ( cwist_redis_pool_t *  pool,
const char *  key 
)

Pool wrapper of cwist_redis_del(): acquires a connection, runs DEL, and releases the connection. See cwist_redis_del() for parameter details.

Definition at line 1193 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_del(), and make_error().

◆ cwist_redis_pool_destroy()

void cwist_redis_pool_destroy ( cwist_redis_pool_t *  pool)

Destroy the pool and close all connections.

Destroy a pool, closing every connection it owns. Safe to call with NULL.

Definition at line 1100 of file cwist_redis.c.

References cap, cwist_free(), and cwist_redis_close().

Referenced by cwist_app_destroy(), and cwist_app_use_redis().

◆ cwist_redis_pool_get()

cwist_error_t cwist_redis_pool_get ( cwist_redis_pool_t *  pool,
const char *  key,
char **  out_value 
)

Pooled convenience commands.

Pool wrapper of cwist_redis_get(): acquires a connection, runs GET, and releases the connection. See cwist_redis_get() for parameter details.

Definition at line 1162 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_get(), and make_error().

◆ cwist_redis_pool_publish()

cwist_error_t cwist_redis_pool_publish ( cwist_redis_pool_t *  pool,
const char *  channel,
const char *  message 
)

Pool wrapper of cwist_redis_publish(): acquires a connection, runs PUBLISH, and releases the connection. See cwist_redis_publish() for parameter details.

Definition at line 1204 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_publish(), and make_error().

◆ cwist_redis_pool_set()

cwist_error_t cwist_redis_pool_set ( cwist_redis_pool_t *  pool,
const char *  key,
const char *  value 
)

Pool wrapper of cwist_redis_set(): acquires a connection, runs SET, and releases the connection. See cwist_redis_set() for parameter details.

Definition at line 1172 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_set(), and make_error().

◆ cwist_redis_pool_setex()

cwist_error_t cwist_redis_pool_setex ( cwist_redis_pool_t *  pool,
const char *  key,
const char *  value,
int  seconds 
)

Pool wrapper of cwist_redis_setex(): acquires a connection, runs SETEX, and releases the connection. See cwist_redis_setex() for parameter details.

Definition at line 1182 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_redis_setex(), and make_error().

◆ cwist_redis_publish()

cwist_error_t cwist_redis_publish ( cwist_redis_t *  r,
const char *  channel,
const char *  message 
)

Publish a message to a channel (PUBLISH).

Parameters
rConnection handle.
channelChannel to publish to.
messageMessage payload.
Returns
Error value indicating success or failure.

Definition at line 941 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_pool_publish().

◆ cwist_redis_reply_free()

void cwist_redis_reply_free ( cwist_redis_reply_t *  reply)

Recursively free a reply tree, including all child elements and string payloads. Safe to call with NULL.

Definition at line 572 of file cwist_redis.c.

References cap, cwist_free(), and cwist_redis_reply_free().

Referenced by cwist_redis_command_argv_reply(), cwist_redis_pool_command_argv_reply_timeout(), and cwist_redis_reply_free().

◆ cwist_redis_select()

cwist_error_t cwist_redis_select ( cwist_redis_t *  r,
unsigned int  database 
)

Select the logical database for subsequent commands (SELECT).

Parameters
rConnection handle.
databaseDatabase index.
Returns
Error value indicating success or failure.

Definition at line 823 of file cwist_redis.c.

References cap, cwist_free(), and cwist_redis_command_argv().

◆ cwist_redis_set()

cwist_error_t cwist_redis_set ( cwist_redis_t *  r,
const char *  key,
const char *  value 
)

Set the value of a key (SET).

Parameters
rConnection handle.
keyKey to write.
valueValue to store.
Returns
Error value indicating success or failure.

Definition at line 857 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_pool_set().

◆ cwist_redis_setex()

cwist_error_t cwist_redis_setex ( cwist_redis_t *  r,
const char *  key,
const char *  value,
int  seconds 
)

Set the value of a key with a time-to-live (SETEX).

Parameters
rConnection handle.
keyKey to write.
valueValue to store.
secondsTTL in seconds; must be positive.
Returns
Error value indicating success or failure.

Definition at line 878 of file cwist_redis.c.

References cap, CWIST_ERR_INT16, cwist_free(), cwist_redis_command(), cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().

Referenced by cwist_redis_pool_setex().

◆ cwist_redis_subscribe()

cwist_error_t cwist_redis_subscribe ( cwist_redis_t *  r,
const char **  channels,
cwist_redis_msg_cb  cb,
void *  ctx 
)

Subscribe to channels on a dedicated connection.

Subscribe to channels and run a blocking message loop, invoking the callback for each incoming message.

Parameters
rConnection handle.
channelsNULL-terminated list of channel names.
cbCallback invoked as cb(channel, message, ctx) per message.
ctxOpaque pointer passed through to the callback.
Returns
Zero error value; the loop ends when the connection is shut down (see cwist_redis_close()).

Definition at line 966 of file cwist_redis.c.

References cap, count, CWIST_ERR_INT16, cwist_free(), CWIST_REDIS_LINE_MAX, cwist_sstring_append(), cwist_sstring_create(), cwist_sstring_destroy(), and make_error().