cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
grpc_channel.h File Reference

gRPC client channel: name resolution, client-side load balancing, and gRFC A6 retry policy on top of cwist_grpc_client. More...

Include dependency graph for grpc_channel.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cwist_grpc_retry_policy
 
struct  cwist_grpc_retry_throttle
 
struct  cwist_grpc_channel_options
 

Macros

#define CWIST_GRPC_STATUS_BIT(code)   (1u << (code))
 

Typedefs

typedef struct cwist_grpc_channel cwist_grpc_channel
 
typedef struct cwist_grpc_channel_call cwist_grpc_channel_call
 
typedef enum cwist_grpc_lb_policy cwist_grpc_lb_policy
 
typedef enum cwist_grpc_channel_state cwist_grpc_channel_state
 
typedef struct cwist_grpc_retry_policy cwist_grpc_retry_policy
 
typedef struct cwist_grpc_retry_throttle cwist_grpc_retry_throttle
 
typedef struct cwist_grpc_channel_options cwist_grpc_channel_options
 

Enumerations

enum  cwist_grpc_lb_policy { CWIST_GRPC_LB_PICK_FIRST = 0 , CWIST_GRPC_LB_ROUND_ROBIN = 1 }
 
enum  cwist_grpc_channel_state {
  CWIST_GRPC_CHANNEL_IDLE = 0 , CWIST_GRPC_CHANNEL_CONNECTING , CWIST_GRPC_CHANNEL_READY , CWIST_GRPC_CHANNEL_TRANSIENT_FAILURE ,
  CWIST_GRPC_CHANNEL_SHUTDOWN
}
 

Functions

cwist_grpc_channel * cwist_grpc_channel_connect (const char *target, const cwist_grpc_channel_options *options)
 Create a channel for target and resolve its backend addresses.
 
void cwist_grpc_channel_close (cwist_grpc_channel *channel)
 Close a channel and free all its resources.
 
cwist_grpc_channel_state cwist_grpc_channel_get_state (cwist_grpc_channel *channel)
 Aggregate connectivity state across subchannels (load-balancing.md).
 
int cwist_grpc_channel_apply_service_config_json (cwist_grpc_channel *channel, const char *json)
 Apply a JSON service config (doc/service_config.md subset, gRFC A6).
 
cwist_grpc_channel_call * cwist_grpc_channel_call_start (cwist_grpc_channel *channel, const char *method, const void *request, size_t request_len, uint64_t timeout_ms)
 Start a unary RPC through the channel, running the gRFC A6 retry engine transparently across attempts.
 
int cwist_grpc_channel_call_recv (cwist_grpc_channel_call *call, cwist_grpc_message *out)
 Receive the next response message of a channel call.
 
cwist_grpc_status_t cwist_grpc_channel_call_finish (cwist_grpc_channel_call *call, const char **message)
 Finish a channel call and return its final gRPC status.
 
void cwist_grpc_channel_call_cancel (cwist_grpc_channel_call *call)
 Cancel the underlying attempt call, if it reached the transport.
 
void cwist_grpc_channel_call_destroy (cwist_grpc_channel_call *call)
 Destroy a channel call and release its resources.
 
uint32_t cwist_grpc_channel_call_attempts (const cwist_grpc_channel_call *call)
 Number of policy attempts a channel call used (transparent retries excluded).
 
cwist_grpc_status_t cwist_grpc_channel_unary (cwist_grpc_channel *channel, const char *method, const void *request, size_t request_len, uint64_t timeout_ms, uint8_t **response, size_t *response_len, char **status_message)
 Convenience blocking unary RPC: start, read one response, finish.
 

Detailed Description

gRPC client channel: name resolution, client-side load balancing, and gRFC A6 retry policy on top of cwist_grpc_client.

A channel resolves one target (doc/naming.md) into a list of backend addresses, keeps one lazily-connected subchannel per address, picks a subchannel per call with the configured LB policy (pick_first default, or round_robin — doc/load-balancing.md), and retries failed RPCs between the channel and the LB pick, so every attempt can land on a different subchannel (gRFC A6).

Subchannel reconnection follows doc/connection-backoff.md: 1s initial backoff, x1.6 multiplier, 120s cap, +/-0.2 jitter, reset once the HTTP/2 SETTINGS handshake completes.

Definition in file grpc_channel.h.

Macro Definition Documentation

◆ CWIST_GRPC_STATUS_BIT

#define CWIST_GRPC_STATUS_BIT (   code)    (1u << (code))

Bit for cwist_grpc_retry_policy::retryable_status_mask (code 0..16).

Definition at line 44 of file grpc_channel.h.

Typedef Documentation

◆ cwist_grpc_channel

typedef struct cwist_grpc_channel cwist_grpc_channel

Definition at line 27 of file grpc_channel.h.

◆ cwist_grpc_channel_call

typedef struct cwist_grpc_channel_call cwist_grpc_channel_call

Definition at line 28 of file grpc_channel.h.

◆ cwist_grpc_channel_options

◆ cwist_grpc_channel_state

◆ cwist_grpc_lb_policy

◆ cwist_grpc_retry_policy

gRFC A6 retryPolicy. Retries are disabled unless a policy is configured (channel option or JSON service config).

◆ cwist_grpc_retry_throttle

gRFC A6 retryThrottling (per channel, i.e. per server name).

Enumeration Type Documentation

◆ cwist_grpc_channel_state

Enumerator
CWIST_GRPC_CHANNEL_IDLE 
CWIST_GRPC_CHANNEL_CONNECTING 
CWIST_GRPC_CHANNEL_READY 
CWIST_GRPC_CHANNEL_TRANSIENT_FAILURE 
CWIST_GRPC_CHANNEL_SHUTDOWN 

Definition at line 35 of file grpc_channel.h.

◆ cwist_grpc_lb_policy

Enumerator
CWIST_GRPC_LB_PICK_FIRST 
CWIST_GRPC_LB_ROUND_ROBIN 

Definition at line 30 of file grpc_channel.h.

Function Documentation

◆ cwist_grpc_channel_apply_service_config_json()

int cwist_grpc_channel_apply_service_config_json ( cwist_grpc_channel *  ch,
const char *  json 
)

Apply a JSON service config (doc/service_config.md subset, gRFC A6).

Apply a JSON service config (doc/service_config.md subset): "loadBalancingConfig" ([{"round_robin":{}}, ...] — first supported policy wins), the deprecated "loadBalancingPolicy" string, "methodConfig" entries with "name" (service/method), "retryPolicy", "waitForReady" and "timeout", and "retryThrottling". Validation follows gRFC A6 (maxAttempts integer greater than 1 clamped to 5, proto3-JSON Duration strings, non-empty retryableStatusCodes in integer or case-insensitive string form, maxTokens in (0,1000], tokenRatio > 0). Returns 0 on success, -1 on a validation error (channel configuration is left unchanged).

Parses loadBalancingConfig (first supported policy wins; deprecated loadBalancingPolicy string also accepted), retryThrottling, and methodConfig (retryPolicy, waitForReady, timeout per name; hedgingPolicy entries carry no policy, as in gRPC C-core). The whole document is validated before anything is swapped in; on error the channel is left untouched.

Return values
0applied
-1invalid JSON, invalid document, or allocation failure

Definition at line 1140 of file grpc_channel.c.

References cap, cwist_alloc(), cwist_free(), CWIST_GRPC_LB_PICK_FIRST, CWIST_GRPC_LB_ROUND_ROBIN, cwist_grpc_retry_throttle::max_tokens, and cwist_grpc_retry_throttle::token_ratio.

◆ cwist_grpc_channel_call_attempts()

uint32_t cwist_grpc_channel_call_attempts ( const cwist_grpc_channel_call *  call)

Number of policy attempts a channel call used (transparent retries excluded).

Number of RPC attempts made (transparent retries excluded, gRFC A6).

Definition at line 685 of file grpc_channel.c.

References cap.

◆ cwist_grpc_channel_call_cancel()

void cwist_grpc_channel_call_cancel ( cwist_grpc_channel_call *  call)

Cancel the underlying attempt call, if it reached the transport.

Definition at line 658 of file grpc_channel.c.

References cap, and cwist_grpc_call_cancel().

◆ cwist_grpc_channel_call_destroy()

void cwist_grpc_channel_call_destroy ( cwist_grpc_channel_call *  cc)

Destroy a channel call and release its resources.

Performs the end-of-call throttle accounting first if finish() did not already. Destroys the underlying call, recycles/releases the subchannel, and frees the handle. NULL-safe.

Definition at line 668 of file grpc_channel.c.

References cap, cwist_free(), cwist_grpc_call_destroy(), and cwist_grpc_call_status().

Referenced by cwist_grpc_channel_unary().

◆ cwist_grpc_channel_call_finish()

cwist_grpc_status_t cwist_grpc_channel_call_finish ( cwist_grpc_channel_call *  cc,
const char **  message 
)

Finish a channel call and return its final gRPC status.

Performs the end-of-call throttle accounting once, if not already done by destroy. For synthetic results, returns the pre-dispatch status and message. message is borrowed (valid until the call is destroyed) and may be NULL.

Definition at line 637 of file grpc_channel.c.

References cap, cwist_grpc_call_finish(), and CWIST_GRPC_INTERNAL.

Referenced by cwist_grpc_channel_unary().

◆ cwist_grpc_channel_call_recv()

int cwist_grpc_channel_call_recv ( cwist_grpc_channel_call *  cc,
cwist_grpc_message *  out 
)

Receive the next response message of a channel call.

Synthetic (pre-dispatch failure) results carry no messages.

Return values
1a message was stored in out
0stream ended (or synthetic result), no more messages
-1invalid arguments

Definition at line 624 of file grpc_channel.c.

References cap, and cwist_grpc_call_recv().

Referenced by cwist_grpc_channel_unary().

◆ cwist_grpc_channel_call_start()

cwist_grpc_channel_call * cwist_grpc_channel_call_start ( cwist_grpc_channel *  ch,
const char *  method,
const void *  request,
size_t  request_len,
uint64_t  timeout_ms 
)

Start a unary RPC through the channel, running the gRFC A6 retry engine transparently across attempts.

Start a call through the channel: picks a subchannel per attempt and applies the retry policy. The returned call is either committed (Response-Headers arrived) or final (all attempts exhausted or a non-retryable failure); recv/finish report its outcome. timeout_ms is the overall call deadline shared by every attempt (A6); each attempt's grpc-timeout header carries the remaining time.

Applies the most specific JSON method config (retry policy, waitForReady, timeout), clamps attempts to GRPC_CHANNEL_MAX_ATTEMPTS_CAP, and retries only while the request fits the per-RPC buffer limit. Blocks until the RPC is committed (Response-Headers or final result), fails with CWIST_GRPC_DEADLINE_EXCEEDED past the deadline, or waits instead of failing when waitForReady is set and no subchannel is ready.

Parameters
method"/package.Service/Method" path
request,request_lenserialized request (may be NULL when 0)
timeout_msper-call deadline, 0 for none (a method-config timeout may shorten it)
Returns
channel call handle, or NULL on invalid arguments/allocation failure

Definition at line 466 of file grpc_channel.c.

References cwist_grpc_retry_policy::backoff_multiplier, cap, cwist_grpc_call_await_headers(), cwist_grpc_call_destroy(), cwist_grpc_call_refused(), cwist_grpc_call_retry_pushback_ms(), cwist_grpc_call_start_ex(), cwist_grpc_call_status(), CWIST_GRPC_DEADLINE_EXCEEDED, CWIST_GRPC_OK, CWIST_GRPC_STATUS_BIT, CWIST_GRPC_UNAVAILABLE, GRPC_CHANNEL_MAX_ATTEMPTS_CAP, cwist_grpc_retry_policy::initial_backoff_ms, cwist_grpc_retry_policy::max_attempts, cwist_grpc_retry_policy::max_backoff_ms, and cwist_grpc_retry_policy::retryable_status_mask.

Referenced by cwist_grpc_channel_unary().

◆ cwist_grpc_channel_close()

void cwist_grpc_channel_close ( cwist_grpc_channel *  ch)

Close a channel and free all its resources.

Calls handed out must be destroyed before closing the channel. NULL-safe.

Definition at line 979 of file grpc_channel.c.

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

Referenced by cwist_grpc_channel_connect().

◆ cwist_grpc_channel_connect()

cwist_grpc_channel * cwist_grpc_channel_connect ( const char *  target,
const cwist_grpc_channel_options *  options 
)

Create a channel for target and resolve its backend addresses.

Resolve target and create a channel. Target syntax (doc/naming.md): dns:[//authority/]host[:port] (default scheme; authority ignored; all resolved addresses are used; default port 443) ipv4:address[:port][,address[:port],...] ipv6:address[:port][,address[:port],...] ([] literals when a port is given) host[:port] (no scheme = dns) Returns NULL when the target is invalid, the scheme is unsupported (unix/vsock/... are not implemented), or no address resolves.

Supported targets: "dns:name" (a "//authority/" prefix is ignored, as in gRPC C-core), "ipv4:1.2.3.4:port,...", "ipv6:[...]:port,...", and a bare name (treated as dns:). unix:, unix-abstract:, and vsock: are not implemented and fail. round_robin dials every address up front; pick_first stays IDLE until the first RPC.

Parameters
optionsmay be NULL for defaults; see cwist_grpc_channel_options
Returns
the new channel, or NULL on any failure (fully cleaned up)

Definition at line 901 of file grpc_channel.c.

References cwist_grpc_channel_options::authority, cap, cwist_grpc_channel_options::connect_timeout_ms, cwist_alloc(), cwist_free(), cwist_grpc_channel_close(), CWIST_GRPC_LB_PICK_FIRST, CWIST_GRPC_LB_ROUND_ROBIN, GRPC_CHANNEL_DEFAULT_BUFFER_LIMIT, GRPC_CHANNEL_MAX_ADDRS, cwist_grpc_channel_options::lb_policy, cwist_grpc_channel_options::per_rpc_buffer_limit, cwist_grpc_channel_options::retry_policy, cwist_grpc_channel_options::retry_throttle, cwist_grpc_channel_options::use_tls, cwist_grpc_channel_options::verify_peer, and cwist_grpc_channel_options::wait_for_ready.

◆ cwist_grpc_channel_get_state()

cwist_grpc_channel_state cwist_grpc_channel_get_state ( cwist_grpc_channel *  ch)

Aggregate connectivity state across subchannels (load-balancing.md).

Aggregated channel connectivity state (doc/load-balancing.md rules).

READY if any subchannel is connected, else IDLE while any subchannel may dial, else TRANSIENT_FAILURE. NULL maps to SHUTDOWN. Thread-safe: takes ch->mu.

Definition at line 1001 of file grpc_channel.c.

References cap, CWIST_GRPC_CHANNEL_IDLE, CWIST_GRPC_CHANNEL_READY, CWIST_GRPC_CHANNEL_SHUTDOWN, CWIST_GRPC_CHANNEL_TRANSIENT_FAILURE, and cwist_grpc_client_dead().

◆ cwist_grpc_channel_unary()

cwist_grpc_status_t cwist_grpc_channel_unary ( cwist_grpc_channel *  ch,
const char *  method,
const void *  request,
size_t  request_len,
uint64_t  timeout_ms,
uint8_t **  response,
size_t *  response_len,
char **  status_message 
)

Convenience blocking unary RPC: start, read one response, finish.

Unary convenience wrapper over cwist_grpc_channel_call_start(): buffers a single response message into response (caller frees; NULL when the call carried none) and returns the final grpc-status. status_message receives an owned copy of grpc-message (caller frees; may be NULL).

On CWIST_GRPC_OK the first response message is copied into response (caller-owned; freed with cwist_free) with its length in response_len; extra messages are discarded. On any other status the response is freed and NULL/0 is returned. Output pointers may be NULL to discard the corresponding value. status_message, when non-NULL on entry, receives an allocated copy of the server status message.

Returns
the final gRPC status (CWIST_GRPC_INTERNAL if the call could not start)

Definition at line 700 of file grpc_channel.c.

References cap, cwist_alloc(), cwist_free(), cwist_grpc_channel_call_destroy(), cwist_grpc_channel_call_finish(), cwist_grpc_channel_call_recv(), cwist_grpc_channel_call_start(), CWIST_GRPC_INTERNAL, and CWIST_GRPC_OK.