-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Proxy-Wasm Redis Host Functions Requirements
Overview
This document outlines the requirements for implementing Redis host functions in the proxy-wasm-java-host to support Higress Proxy-Wasm plugins that require Redis functionality. The ai-quota plugin and other Higress plugins depend on these host functions to perform Redis operations.
Background
Higress Proxy-Wasm plugins such as ai-quota, ai-cache, ai-history, replay-protection, cluster-key-rate-limit, ai-token-ratelimit, and ai-load-balancer require Redis functionality for:
- Quota management and rate limiting
- Caching AI responses
- Session management
- Load balancing state
- Replay attack protection
These plugins expect Redis host functions to be available in the Proxy-Wasm host environment, but the current proxy-wasm-java-host implementation does not include Redis support.
Required Host Functions
Based on the Higress source code analysis, the following three host functions must be implemented. These functions are called from WASM modules and must be registered in the host environment.
1. env.proxy_redis_init
Purpose: Initialize a Redis connection for a specific upstream cluster.
WASM Function Signature:
fn proxy_redis_init(
upstream_ptr: i32,
upstream_len: i32,
username_ptr: i32,
username_len: i32,
password_ptr: i32,
password_len: i32,
timeout: i32
) -> i32Parameter Mapping:
upstream_ptr(i32): Pointer to the upstream string in WASM memoryupstream_len(i32): Length of the upstream string in bytesusername_ptr(i32): Pointer to the username string in WASM memory (can be 0 if null)username_len(i32): Length of the username string in bytes (can be 0 if null)password_ptr(i32): Pointer to the password string in WASM memory (can be 0 if null)password_len(i32): Length of the password string in bytes (can be 0 if null)timeout(i32): Connection timeout duration in milliseconds
Return Value:
0(i32): Success1(i32): Error (connection failed, invalid parameters, etc.)
2. env.proxy_dispatch_redis_call
Purpose: Dispatch a Redis command to the specified upstream cluster.
WASM Function Signature:
fn proxy_dispatch_redis_call(
upstream_ptr: i32,
upstream_len: i32,
query_ptr: i32,
query_len: i32,
callback_ptr: i32
) -> i32Parameter Mapping:
upstream_ptr(i32): Pointer to the upstream string in WASM memoryupstream_len(i32): Length of the upstream string in bytesquery_ptr(i32): Pointer to the Redis command bytes in WASM memory (RESP format)query_len(i32): Length of the Redis command in bytescallback_ptr(i32): Pointer to the callback function in WASM memory
Return Value:
token_id(i32): Unique identifier for this Redis call (positive integer)-1(i32): Error (invalid upstream, connection failed, etc.)
WASM Callback Function Signature:
fn redis_callback(
token_id: i32,
status: i32,
response_size: i32
)WASM Callback Parameters:
token_id(i32): The token ID returned from the dispatch callstatus(i32): Status code (0 = success, 1 = error)response_size(i32): Size of the response data in bytes
WASM Callback Invocation:
private void callWasmCallback(int callbackPtr, int tokenId, int status, int responseSize) {
// Call the WASM function at callbackPtr with parameters:
// - tokenId: the unique identifier for this Redis call
// - status: 0 for success, 1 for error
// - responseSize: the size of the response data
wasmInstance.callFunction(callbackPtr, tokenId, status, responseSize);
}3. env.proxy_get_redis_call_response
Purpose: Retrieve the response data from a completed Redis call.
WASM Function Signature:
fn proxy_get_redis_call_response(
start: i32,
max_size: i32
) -> i32Parameter Mapping:
start(i32): Starting offset in the response buffer (typically 0)max_size(i32): Maximum number of bytes to read (typically the response_size from the callback)
Return Value:
response_ptr(i32): Pointer to response data in WASM memory (positive integer)-1(i32): Error (no data available, invalid parameters, etc.)
Response Data Format:
The response data is returned in RESP (Redis Serialization Protocol) format. The WASM module is responsible for:
- Reading the response data from the returned pointer
- Parsing the RESP format
- Converting to the appropriate data type (string, integer, array, etc.)
4. Connection Pooling/Cleanup
Redis connections should ideally be pooled and their lifecycle be tied to the plugin lifecycle too.