forked from valkey-io/valkey-glide
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Yury-Fridlyand <[email protected]>
- Loading branch information
1 parent
0820f8a
commit e759ed4
Showing
9 changed files
with
469 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
|
||
package api | ||
|
||
// #cgo LDFLAGS: -L../target/release -lglide_rs | ||
// #include "../lib.h" | ||
// | ||
// void successCallback(uintptr_t channelPtr, char *message); | ||
// void failureCallback(uintptr_t channelPtr, char *errMessage, RequestErrorType errType); | ||
import "C" | ||
|
||
import ( | ||
"github.com/aws/glide-for-redis/go/glide/protobuf" | ||
"google.golang.org/protobuf/proto" | ||
"unsafe" | ||
) | ||
|
||
//export successCallback | ||
func successCallback(channelPtr C.uintptr_t, cResponse *C.char) { | ||
response := C.GoString(cResponse) | ||
goChannelPointer := uintptr(channelPtr) | ||
resultChannel := *(*chan payload)(unsafe.Pointer(goChannelPointer)) | ||
resultChannel <- payload{value: &response, error: nil} | ||
} | ||
|
||
//export failureCallback | ||
func failureCallback(channelPtr C.uintptr_t, cErrorMessage *C.char, cErrorType C.RequestErrorType) { | ||
goChannelPointer := uintptr(channelPtr) | ||
resultChannel := *(*chan payload)(unsafe.Pointer(goChannelPointer)) | ||
resultChannel <- payload{value: nil, error: goError(cErrorType, cErrorMessage)} | ||
} | ||
|
||
type connectionRequestConverter interface { | ||
toProtobuf() *protobuf.ConnectionRequest | ||
} | ||
|
||
type baseClient struct { | ||
coreClient unsafe.Pointer | ||
} | ||
|
||
func createClient(converter connectionRequestConverter) (unsafe.Pointer, error) { | ||
request := converter.toProtobuf() | ||
msg, err := proto.Marshal(request) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
byteCount := len(msg) | ||
requestBytes := C.CBytes(msg) | ||
cResponse := (*C.struct_ConnectionResponse)(C.create_client_using_protobuf((*C.uchar)(requestBytes), C.uintptr_t(byteCount), (C.SuccessCallback)(unsafe.Pointer(C.successCallback)), (C.FailureCallback)(unsafe.Pointer(C.failureCallback)))) | ||
defer C.free_connection_response(cResponse) | ||
|
||
cErr := cResponse.error_message | ||
if cErr != nil { | ||
return nil, goError(cResponse.error_type, cResponse.error_message) | ||
} | ||
|
||
return cResponse.conn_ptr, nil | ||
} | ||
|
||
// Close terminates the client by closing all associated resources. | ||
func (client *baseClient) Close() error { | ||
if client.coreClient == nil { | ||
return &GlideError{"The glide client was not open. Either it was not initialized, or it was already closed."} | ||
} | ||
|
||
C.close_client(client.coreClient) | ||
client.coreClient = nil | ||
return nil | ||
} | ||
|
||
func (client *baseClient) CustomCommand(args []string) (interface{}, error) { | ||
cArgs := toCStrings(args) | ||
defer freeCStrings(cArgs) | ||
|
||
resultChannel := make(chan payload) | ||
resultChannelPtr := uintptr(unsafe.Pointer(&resultChannel)) | ||
|
||
requestType := C.uint32_t(customCommand) | ||
C.command(client.coreClient, C.uintptr_t(resultChannelPtr), requestType, C.uintptr_t(len(args)), &cArgs[0]) | ||
|
||
payload := <-resultChannel | ||
if payload.error != nil { | ||
return nil, payload.error | ||
} | ||
|
||
if payload.value != nil { | ||
return *payload.value, nil | ||
} | ||
|
||
return nil, nil | ||
} | ||
|
||
func toCStrings(args []string) []*C.char { | ||
cArgs := make([]*C.char, len(args)) | ||
for i, arg := range args { | ||
cString := C.CString(arg) | ||
cArgs[i] = cString | ||
} | ||
return cArgs | ||
} | ||
|
||
func freeCStrings(cArgs []*C.char) { | ||
for _, arg := range cArgs { | ||
C.free(unsafe.Pointer(arg)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
|
||
package api | ||
|
||
// RedisClusterClient is a client used for connection to cluster Redis servers. | ||
type RedisClusterClient struct { | ||
baseClient | ||
} | ||
|
||
// CreateClusterClient creates a Redis client in cluster mode using the given [RedisClusterClientConfiguration]. | ||
func CreateClusterClient(config *RedisClusterClientConfiguration) (*RedisClusterClient, error) { | ||
connPtr, err := createClient(config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &RedisClusterClient{baseClient{connPtr}}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
|
||
package api | ||
|
||
// #cgo LDFLAGS: -L../target/release -lglide_rs | ||
// #include "../lib.h" | ||
import "C" | ||
|
||
type GlideError struct { | ||
msg string | ||
} | ||
|
||
func (e GlideError) Error() string { return e.msg } | ||
|
||
type RequestError struct { | ||
msg string | ||
} | ||
|
||
func (e *RequestError) Error() string { return e.msg } | ||
|
||
type ExecAbortError struct { | ||
msg string | ||
} | ||
|
||
func (e *ExecAbortError) Error() string { return e.msg } | ||
|
||
type TimeoutError struct { | ||
msg string | ||
} | ||
|
||
func (e *TimeoutError) Error() string { return e.msg } | ||
|
||
type DisconnectError struct { | ||
msg string | ||
} | ||
|
||
func (e *DisconnectError) Error() string { return e.msg } | ||
|
||
func goError(cErrorType C.RequestErrorType, cErrorMessage *C.char) error { | ||
msg := C.GoString(cErrorMessage) | ||
switch cErrorType { | ||
case C.ExecAbort: | ||
return &ExecAbortError{msg} | ||
case C.Timeout: | ||
return &TimeoutError{msg} | ||
case C.Disconnect: | ||
return &DisconnectError{msg} | ||
default: | ||
return &RequestError{msg} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
|
||
package api | ||
|
||
// #cgo LDFLAGS: -L../target/release -lglide_rs | ||
// #include "../lib.h" | ||
import "C" | ||
|
||
type payload struct { | ||
value *string | ||
error error | ||
} | ||
|
||
type RequestType uint32 | ||
|
||
const ( | ||
_ = iota | ||
customCommand RequestType = iota | ||
getString | ||
setString | ||
ping | ||
info | ||
del | ||
selectDB | ||
configGet | ||
configSet | ||
configResetStat | ||
configRewrite | ||
clientGetName | ||
clientGetRedir | ||
clientId | ||
clientInfo | ||
clientKill | ||
clientList | ||
clientNoEvict | ||
clientNoTouch | ||
clientPause | ||
clientReply | ||
clientSetInfo | ||
clientSetName | ||
clientUnblock | ||
clientUnpause | ||
expire | ||
hashSet | ||
hashGet | ||
hashDel | ||
hashExists | ||
mGet | ||
mSet | ||
incr | ||
incrBy | ||
decr | ||
incrByFloat | ||
decrBy | ||
hashGetAll | ||
hashMSet | ||
hashMGet | ||
hashIncrBy | ||
hashIncrByFloat | ||
lPush | ||
lPop | ||
rPush | ||
rPop | ||
lLen | ||
lRem | ||
lRange | ||
lTrim | ||
sAdd | ||
sRem | ||
sMembers | ||
sCard | ||
pExpireAt | ||
pExpire | ||
expireAt | ||
exists | ||
unlink | ||
ttl | ||
zAdd | ||
zRem | ||
zRange | ||
zCard | ||
zCount | ||
zIncrBy | ||
zScore | ||
keyType | ||
hLen | ||
echo | ||
zPopMin | ||
strlen | ||
lIndex | ||
zPopMax | ||
xRead | ||
xAdd | ||
xReadGroup | ||
xAck | ||
xTrim | ||
xGroupCreate | ||
xGroupDestroy | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
*/ | ||
|
||
package api | ||
|
||
import "C" | ||
|
||
// RedisClient is a client used for connection to standalone Redis servers. | ||
type RedisClient struct { | ||
baseClient | ||
} | ||
|
||
// CreateClient creates a Redis client in standalone mode using the given [RedisClientConfiguration]. | ||
func CreateClient(config *RedisClientConfiguration) (*RedisClient, error) { | ||
connPtr, err := createClient(config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &RedisClient{baseClient{connPtr}}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0 | ||
*/ | ||
package glide | ||
|
||
/* | ||
#cgo LDFLAGS: -L../target/release -lglide_rs | ||
#include "../lib.h" | ||
void successCallback(uintptr_t channelPtr, char *message); | ||
void failureCallback(uintptr_t channelPtr, char *errMessage, RequestErrorType errType); | ||
*/ | ||
import "C" | ||
|
||
import ( | ||
"fmt" | ||
"github.com/aws/glide-for-redis/go/glide/protobuf" | ||
"google.golang.org/protobuf/proto" | ||
"unsafe" | ||
) | ||
|
||
type GlideRedisClient struct { | ||
coreClient unsafe.Pointer | ||
} | ||
|
||
type payload struct { | ||
value string | ||
errMessage error | ||
} | ||
|
||
type RequestType uint32 | ||
|
||
type ErrorType uint32 | ||
|
||
const ( | ||
ClosingError = iota | ||
RequestError | ||
TimeoutError | ||
ExecAbortError | ||
ConnectionError | ||
) | ||
|
||
//export successCallback | ||
func successCallback(channelPtr C.uintptr_t, message *C.char) { | ||
// TODO: Implement when we implement the command logic | ||
} | ||
|
||
//export failureCallback | ||
func failureCallback(channelPtr C.uintptr_t, errMessage *C.char, errType C.RequestErrorType) { | ||
// TODO: Implement when we implement the command logic | ||
} | ||
|
||
func (glideRedisClient *GlideRedisClient) ConnectToRedis(request *protobuf.ConnectionRequest) error { | ||
marshalledRequest, err := proto.Marshal(request) | ||
if err != nil { | ||
return fmt.Errorf("Failed to encode connection request: %v", err) | ||
} | ||
byteCount := len(marshalledRequest) | ||
requestBytes := C.CBytes(marshalledRequest) | ||
response := (*C.struct_ConnectionResponse)(C.create_client_using_protobuf((*C.uchar)(requestBytes), C.uintptr_t(byteCount), (C.SuccessCallback)(unsafe.Pointer(C.successCallback)), (C.FailureCallback)(unsafe.Pointer(C.failureCallback)))) | ||
defer C.free_connection_response(response) | ||
if response.error_message != nil { | ||
return fmt.Errorf(C.GoString(response.error_message)) | ||
} | ||
glideRedisClient.coreClient = response.conn_ptr | ||
return nil | ||
} | ||
|
||
func (glideRedisClient *GlideRedisClient) CloseClient() error { | ||
if glideRedisClient.coreClient == nil { | ||
return fmt.Errorf("Cannot close glide client before it has been created.") | ||
} | ||
C.close_client(glideRedisClient.coreClient) | ||
return nil | ||
} |
Oops, something went wrong.