|
cwist
Modern C web framework with libttak runtime
|
gRPC client channel: name resolution (doc/naming.md), client-side load balancing (doc/load-balancing.md), connection backoff (doc/connection-backoff.md), and the gRFC A6 retry engine. More...
#include <cwist/net/grpc/grpc_channel.h>#include <cwist/core/mem/alloc.h>#include <cjson/cJSON.h>#include <arpa/inet.h>#include <netdb.h>#include <pthread.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <time.h>#include <unistd.h>
Go to the source code of this file.
Macros | |
| #define | _POSIX_C_SOURCE 200809L |
| #define | GRPC_CHANNEL_MAX_ADDRS 64 |
| #define | GRPC_CHANNEL_DEFAULT_BUFFER_LIMIT (256u * 1024u) |
| #define | GRPC_CHANNEL_MAX_ATTEMPTS_CAP 5 |
| #define | GRPC_CHANNEL_CONN_BACKOFF_INITIAL_MS 1000.0 |
| #define | GRPC_CHANNEL_CONN_BACKOFF_MULTIPLIER 1.6 |
| #define | GRPC_CHANNEL_CONN_BACKOFF_MAX_MS 120000.0 |
| #define | GRPC_CHANNEL_CONN_BACKOFF_JITTER 0.2 |
Typedefs | |
| typedef struct cwist_grpc_subchannel | cwist_grpc_subchannel |
| typedef struct grpc_method_config | grpc_method_config |
Functions | |
| 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. | |
| int | cwist_grpc_channel_call_recv (cwist_grpc_channel_call *cc, 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 *cc, const char **message) |
| Finish a channel call and return its final gRPC status. | |
| void | cwist_grpc_channel_call_cancel (cwist_grpc_channel_call *cc) |
| Cancel the underlying attempt call, if it reached the transport. | |
| void | cwist_grpc_channel_call_destroy (cwist_grpc_channel_call *cc) |
| Destroy a channel call and release its resources. | |
| uint32_t | cwist_grpc_channel_call_attempts (const cwist_grpc_channel_call *cc) |
| Number of policy attempts a channel call used (transparent retries excluded). | |
| 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. | |
| 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 *ch) |
| Close a channel and free all its resources. | |
| cwist_grpc_channel_state | cwist_grpc_channel_get_state (cwist_grpc_channel *ch) |
| Aggregate connectivity state across subchannels (load-balancing.md). | |
| 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). | |
gRPC client channel: name resolution (doc/naming.md), client-side load balancing (doc/load-balancing.md), connection backoff (doc/connection-backoff.md), and the gRFC A6 retry engine.
Layout mirrors gRPC: channel -> resolver -> subchannels (one per backend address) -> LB policy -> per-call pick. Retries live between the channel and the LB policy so every attempt can use a different subchannel (A6).
Retry engine notes (all gRFC A6):
Definition in file grpc_channel.c.
Definition at line 27 of file grpc_channel.c.
| #define GRPC_CHANNEL_CONN_BACKOFF_INITIAL_MS 1000.0 |
Definition at line 45 of file grpc_channel.c.
| #define GRPC_CHANNEL_CONN_BACKOFF_JITTER 0.2 |
Definition at line 48 of file grpc_channel.c.
| #define GRPC_CHANNEL_CONN_BACKOFF_MAX_MS 120000.0 |
Definition at line 47 of file grpc_channel.c.
| #define GRPC_CHANNEL_CONN_BACKOFF_MULTIPLIER 1.6 |
Definition at line 46 of file grpc_channel.c.
| #define GRPC_CHANNEL_DEFAULT_BUFFER_LIMIT (256u * 1024u) |
Definition at line 41 of file grpc_channel.c.
| #define GRPC_CHANNEL_MAX_ADDRS 64 |
Definition at line 40 of file grpc_channel.c.
| #define GRPC_CHANNEL_MAX_ATTEMPTS_CAP 5 |
Definition at line 42 of file grpc_channel.c.
Apply a JSON service config (doc/service_config.md subset, gRFC A6).
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.
| 0 | applied |
| -1 | invalid 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.
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.
| void cwist_grpc_channel_call_cancel | ( | cwist_grpc_channel_call * | cc | ) |
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().
| 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_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().
| 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.
| 1 | a message was stored in out |
| 0 | stream ended (or synthetic result), no more messages |
| -1 | invalid 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 * 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.
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.
| method | "/package.Service/Method" path |
| request,request_len | serialized request (may be NULL when 0) |
| timeout_ms | per-call deadline, 0 for none (a method-config timeout may shorten it) |
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().
| 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 * cwist_grpc_channel_connect | ( | const char * | target, |
| const cwist_grpc_channel_options * | options | ||
| ) |
Create a channel for target and resolve its backend addresses.
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.
| options | may be NULL for defaults; see cwist_grpc_channel_options |
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_state cwist_grpc_channel_get_state | ( | cwist_grpc_channel * | ch | ) |
Aggregate connectivity state across subchannels (load-balancing.md).
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_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.
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.
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.