From 32789424ba568da737899018011a88ddb0dbc8ab Mon Sep 17 00:00:00 2001 From: Jonathan Louie Date: Thu, 29 Feb 2024 10:15:50 -0800 Subject: [PATCH] Update API for client creation --- go/examples/main.go | 12 +++++++++++- go/glide/glide.go | 18 ++++++++++++------ go/glide/lib.h | 9 ++++----- go/go.mod | 1 + go/go.sum | 7 +++++++ go/src/lib.rs | 46 ++++++++++++--------------------------------- 6 files changed, 47 insertions(+), 46 deletions(-) diff --git a/go/examples/main.go b/go/examples/main.go index a9ba719ba2..2f88bffd98 100644 --- a/go/examples/main.go +++ b/go/examples/main.go @@ -6,13 +6,23 @@ package main import ( "fmt" "github.com/aws/glide-for-redis/go/glide/glide" + "github.com/aws/glide-for-redis/go/glide/protobuf" ) func main() { fmt.Println("Starting go-glide client...") client := glide.GlideRedisClient{} - err := client.ConnectToRedis("localhost", 6379, false, false) + request := &protobuf.ConnectionRequest{ + TlsMode: protobuf.TlsMode_NoTls, + ClusterModeEnabled: false, + ReadFrom: protobuf.ReadFrom_Primary, + } + request.Addresses = append( + request.Addresses, + &protobuf.NodeAddress{Host: "localhost", Port: uint32(6379)}, + ) + err := client.ConnectToRedis(request) if err != nil { return } diff --git a/go/glide/glide.go b/go/glide/glide.go index f8a1bec583..2b24239457 100644 --- a/go/glide/glide.go +++ b/go/glide/glide.go @@ -15,6 +15,8 @@ import "C" import ( "fmt" "unsafe" + "github.com/aws/glide-for-redis/go/glide/protobuf" + "github.com/golang/protobuf/proto" ) type GlideRedisClient struct { @@ -154,13 +156,17 @@ func freeCStrings(cArgs []*C.char) { } } -func (glideRedisClient *GlideRedisClient) ConnectToRedis(host string, port int, useSSL bool, clusterModeEnabled bool) error { - caddress := C.CString(host) - defer C.free(unsafe.Pointer(caddress)) - - response := (C.struct_ConnectionResponse)(C.create_client(caddress, C.uint32_t(port), C._Bool(useSSL), (C.SuccessCallback)(unsafe.Pointer(C.successCallback)), (C.FailureCallback)(unsafe.Pointer(C.failureCallback)))) +func (glideRedisClient *GlideRedisClient) ConnectToRedis(request *protobuf.ConnectionRequest) error { + marshalledRequest, err := proto.Marshal(request) + if err != nil { + return fmt.Errorf("Failed to encode connection request:", err) + } + byteCount := len(marshalledRequest) + requestBytes := C.CBytes(marshalledRequest) + response := (*C.struct_ConnectionResponse)(C.create_client((*C.uchar)(requestBytes), C.uintptr_t(byteCount), (C.SuccessCallback)(unsafe.Pointer(C.successCallback)), (C.FailureCallback)(unsafe.Pointer(C.failureCallback)))) + defer C.free(unsafe.Pointer(response)) if response.error != nil { - return fmt.Errorf("Connection error: ", C.GoString(response.error.message)) + return fmt.Errorf(C.GoString(response.error.message)) } glideRedisClient.coreClient = response.conn_ptr return nil diff --git a/go/glide/lib.h b/go/glide/lib.h index 316432ad16..71591c29da 100644 --- a/go/glide/lib.h +++ b/go/glide/lib.h @@ -118,11 +118,10 @@ typedef void (*FailureCallback)(uintptr_t channel_address, const char *err_messa /** * Creates a new client to the given address. The success callback needs to copy the given string synchronously, since it will be dropped by Rust once the callback returns. All callbacks should be offloaded to separate threads in order not to exhaust the client's thread pool. */ -struct ConnectionResponse create_client(const char *host, - uint32_t port, - bool use_tls, - SuccessCallback success_callback, - FailureCallback failure_callback); +const struct ConnectionResponse *create_client(const uint8_t *connection_request, + uintptr_t request_len, + SuccessCallback success_callback, + FailureCallback failure_callback); void close_client(const void *client_ptr); diff --git a/go/go.mod b/go/go.mod index e5c99d1988..2e4ede8147 100644 --- a/go/go.mod +++ b/go/go.mod @@ -10,6 +10,7 @@ require ( require ( github.com/BurntSushi/toml v1.2.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/go/go.sum b/go/go.sum index 4ccef17d5a..26671898ba 100644 --- a/go/go.sum +++ b/go/go.sum @@ -57,11 +57,15 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -272,6 +276,7 @@ golang.org/x/tools v0.12.1-0.20230825192346-2191a27a6dc5 h1:Vk4mysSz+GqQK2eqgWbo golang.org/x/tools v0.12.1-0.20230825192346-2191a27a6dc5/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -293,6 +298,8 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= diff --git a/go/src/lib.rs b/go/src/lib.rs index 411429cdac..e9097f24e7 100644 --- a/go/src/lib.rs +++ b/go/src/lib.rs @@ -1,8 +1,9 @@ +use glide_core::client::Client as GlideClient; /** * Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 */ use glide_core::connection_request; -use glide_core::{client::Client as GlideClient, connection_request::NodeAddress}; +use protobuf::Message; use redis::{cmd, Cmd, FromRedisValue, RedisResult, Value}; use std::{ ffi::{c_void, CStr, CString}, @@ -52,37 +53,13 @@ pub struct Client { runtime: Runtime, } -fn create_connection_request( - host: String, - port: u32, - use_tls: bool, -) -> connection_request::ConnectionRequest { - let mut address_info = NodeAddress::new(); - address_info.host = host.to_string().into(); - address_info.port = port; - let addresses_info = vec![address_info]; - let mut connection_request = connection_request::ConnectionRequest::new(); - connection_request.addresses = addresses_info; - connection_request.tls_mode = if use_tls { - connection_request::TlsMode::SecureTls - } else { - connection_request::TlsMode::NoTls - } - .into(); - - connection_request -} - fn create_client_internal( - host: *const c_char, - port: u32, - use_tls: bool, + connection_request_bytes: &[u8], success_callback: SuccessCallback, failure_callback: FailureCallback, ) -> RedisResult { - let host_cstring = unsafe { CStr::from_ptr(host as *mut c_char) }; - let host_string = host_cstring.to_str()?.to_string(); - let request = create_connection_request(host_string, port, use_tls); + let request = + connection_request::ConnectionRequest::parse_from_bytes(connection_request_bytes).unwrap(); let runtime = Builder::new_multi_thread() .enable_all() .thread_name("GLIDE for Redis Go thread") @@ -100,13 +77,13 @@ fn create_client_internal( /// Creates a new client to the given address. The success callback needs to copy the given string synchronously, since it will be dropped by Rust once the callback returns. All callbacks should be offloaded to separate threads in order not to exhaust the client's thread pool. #[no_mangle] pub extern "C" fn create_client( - host: *const c_char, - port: u32, - use_tls: bool, + connection_request: *const u8, + request_len: usize, success_callback: SuccessCallback, failure_callback: FailureCallback, -) -> ConnectionResponse { - match create_client_internal(host, port, use_tls, success_callback, failure_callback) { +) -> *const ConnectionResponse { + let request_bytes = unsafe { std::slice::from_raw_parts(connection_request, request_len) }; + let response = match create_client_internal(request_bytes, success_callback, failure_callback) { Err(err) => { let message_cstring = CString::new(err.to_string()).unwrap(); ConnectionResponse { @@ -121,7 +98,8 @@ pub extern "C" fn create_client( conn_ptr: Box::into_raw(Box::new(client)) as *const c_void, error: std::ptr::null(), }, - } + }; + Box::into_raw(Box::new(response)) } #[no_mangle]