Skip to content

Commit

Permalink
add response handler for BZPopMin
Browse files Browse the repository at this point in the history
Signed-off-by: jbrinkman <[email protected]>
  • Loading branch information
jbrinkman committed Dec 24, 2024
1 parent 531a993 commit 16ed74b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 32 deletions.
6 changes: 3 additions & 3 deletions go/api/base_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1371,11 +1371,11 @@ func (client *baseClient) ZPopMaxWithCount(key string, count int64) (map[Result[
return handleStringDoubleMapResponse(result)
}

func (client *baseClient) BZPopMin(keys []string, timeoutSecs float64) ([]Result[string], error) {
func (client *baseClient) BZPopMin(keys []string, timeoutSecs float64) (Result[KeyWithMemberAndScore], error) {
result, err := client.executeCommand(C.BZPopMin, append(keys, utils.FloatToString(timeoutSecs)))
if err != nil {
return nil, err
return CreateNilKeyWithMemberAndScoreResult(), err
}

return handleStringArrayOrNullResponse(result)
return handleKeyWithMemberAndScoreResponse(result)
}
30 changes: 30 additions & 0 deletions go/api/response_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,36 @@ func handleStringSetResponse(response *C.struct_CommandResponse) (map[Result[str
return slice, nil
}

func describe(i interface{}) {
fmt.Printf("(%v, %T)\n", i, i)
}

func handleKeyWithMemberAndScoreResponse(response *C.struct_CommandResponse) (Result[KeyWithMemberAndScore], error) {
defer C.free_command_response(response)

describe(response)
typeErr := checkResponseType(response, C.Array, false)
if typeErr != nil {
return CreateNilKeyWithMemberAndScoreResult(), typeErr
}

return CreateNilKeyWithMemberAndScoreResult(), nil
// m := make(map[Result[string]]Result[float64], response.array_value_len)
// for _, v := range unsafe.Slice(response.array_value, response.array_value_len) {
// key, err := convertCharArrayToString(v.map_key, true)
// if err != nil {
// return nil, err
// }
// value, err := handleDoubleResponse(v.map_value)
// if err != nil {
// return nil, err
// }
// m[key] = value
// }

// return m, nil
}

func handleScanResponse(
response *C.struct_CommandResponse,
) (Result[string], []Result[string], error) {
Expand Down
13 changes: 13 additions & 0 deletions go/api/response_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ type Result[T any] struct {
isNil bool
}

type KeyWithMemberAndScore struct {
Key, Member string
Score float64
}

func (result Result[T]) IsNil() bool {
return result.isNil
}
Expand Down Expand Up @@ -47,6 +52,14 @@ func CreateNilBoolResult() Result[bool] {
return Result[bool]{val: false, isNil: true}
}

func CreateKeyWithMemberAndScoreResult(kmsVal KeyWithMemberAndScore) Result[KeyWithMemberAndScore] {
return Result[KeyWithMemberAndScore]{val: kmsVal, isNil: false}
}

func CreateNilKeyWithMemberAndScoreResult() Result[KeyWithMemberAndScore] {
return Result[KeyWithMemberAndScore]{val: KeyWithMemberAndScore{"", "", 0.0}, isNil: true}
}

// Enum to distinguish value types stored in `ClusterValue`
type ValueType int

Expand Down
4 changes: 2 additions & 2 deletions go/api/sorted_set_commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,6 @@ type SortedSetCommands interface {
// [valkey.io]: https://valkey.io/commands/zpopmin/
ZPopMaxWithCount(key string, count int64) (map[Result[string]]Result[float64], error)

// [valkey bzpopmin]: https://valkey.io/commands/bzpopmin/
BZPopMin(keys []string, timeoutSecs float64) ([]Result[string], error)
// [valkey.io]: https://valkey.io/commands/bzpopmin/
BZPopMin(keys []string, timeoutSecs float64) (Result[KeyWithMemberAndScore], error)
}
56 changes: 29 additions & 27 deletions go/integTest/shared_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3969,46 +3969,48 @@ func (suite *GlideTestSuite) TestZincrBy() {
assert.NotNil(suite.T(), err)
assert.IsType(suite.T(), &api.RequestError{}, err)
})
}

func (suite *GlideTestSuite) TestBZPopMin() {
suite.runWithDefaultClients(func(client api.BaseClient) {
key1 := "{listKey}-1-" + uuid.NewString()
// key2 := "{listKey}-2-" + uuid.NewString()
key2 := "{listKey}-2-" + uuid.NewString()
key3 := "{listKey}-2-" + uuid.NewString()

// Add elements to key1
zaddResult1, err := client.ZAdd(key1, map[string]float64{"a": 1.0, "b": 1.5})
assert.Nil(suite.T(), err)
assert.Equal(suite.T(), int64(2), zaddResult1.Value())

// Add elements to key2
// zaddResult2, err := client.ZAdd(key2, map[string]float64{"c": 2.0})
// assert.Nil(suite.T(), err)
// assert.Equal(suite.T(), int64(1), zaddResult2.Value())

// // Pop minimum element from key1 and key2
// bzpopminResult1, err := client.BZPopMin([]string{key1, key2}, 500*time.Millisecond)
// assert.NoError(suite.T(), err)
// assert.Equal(suite.T() []interface{}{key1, "a", 1.0}, bzpopminResult1)

// // Attempt to pop from non-existent key3
// bzpopminResult2, err := client.BZPopMin([]string{key3}, 1*time.Second)
// assert.NoError(suite.T() err)
// assert.Nil(suite.T() bzpopminResult2)

// // Pop minimum element from key2
// bzpopminResult3, err := client.BZPopMin([]string{key3, key2}, 500*time.Millisecond)
// assert.NoError(suite.T() err)
// assert.Equal(suite.T() []interface{}{key2, "c", 2.0}, bzpopminResult3)

// // Set key3 to a non-sorted set value
// setResult, err := client.Set(key3, "value")
// assert.NoError(suite.T() err)
// assert.Equal(suite.T() "OK", setResult)
zaddResult2, err := client.ZAdd(key2, map[string]float64{"c": 2.0})
assert.Nil(suite.T(), err)
assert.Equal(suite.T(), int64(1), zaddResult2.Value())

// Pop minimum element from key1 and key2
bzpopminResult1, err := client.BZPopMin([]string{key1, key2}, float64(500*time.Millisecond))
assert.Nil(suite.T(), err)
assert.Equal(suite.T(), []interface{}{key1, "a", 1.0}, bzpopminResult1)

// Attempt to pop from non-existent key3
bzpopminResult2, err := client.BZPopMin([]string{key3}, float64(1*time.Second))
assert.Nil(suite.T(), err)
assert.Nil(suite.T(), bzpopminResult2)

// Pop minimum element from key2
bzpopminResult3, err := client.BZPopMin([]string{key3, key2}, float64(500*time.Millisecond))
assert.Nil(suite.T(), err)
assert.Equal(suite.T(), []interface{}{key2, "c", 2.0}, bzpopminResult3)

// Set key3 to a non-sorted set value
setResult, err := client.Set(key3, "value")
assert.Nil(suite.T(), err)
assert.Equal(suite.T(), "OK", setResult)

// // Attempt to pop from key3 which is not a sorted set
// _, err = client.BZPopMin([]string{key3}, 500*time.Millisecond)
// assert.Error(suite.T() err)
// assert.IsType(suite.T() RequestException{}, err)
// _, err = client.BZPopMin([]string{key3}, float64(500*time.Millisecond))
// assert.Error(suite.T(), err)
// assert.IsType(suite.T(), RequestException{}, err)
})
}

Expand Down

0 comments on commit 16ed74b

Please sign in to comment.