Skip to content

Commit

Permalink
api: use iproto types and constants for the protocol
Browse files Browse the repository at this point in the history
Replaced the local `ProtocolFeature` type with the
`iproto.Feature`.
Replaced local `Feature` constants with their
`iproto.IPROTO_FEATURE_` analogues.

Closes #337
  • Loading branch information
DerekBum committed Oct 30, 2023
1 parent 28e6023 commit a916922
Show file tree
Hide file tree
Showing 15 changed files with 167 additions and 188 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
`pool.Connect` and `pool.Add` now accept context as first argument, which
user may cancel in process. If `pool.Connect` is canceled in progress, an
error will be returned. All created connections will be closed.
- `iproto.Feature` type now used instead of `ProtocolFeature` (#337)
- `iproto.IPROTO_FEATURE_` constants now used instead of local `Feature`
constants for `protocol` (#337)

### Deprecated

Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,11 @@ now does not attempt to reconnect and tries to establish a connection only once.
Function might be canceled via context. Context accepted as first argument,
and user may cancel it in process.

#### Protocol changes

* `iproto.Feature` type used instead of `ProtocolFeature`.
* `iproto.IPROTO_FEATURE_` constants used instead of local ones.

## Contributing

See [the contributing guide](CONTRIBUTING.md) for detailed instructions on how
Expand Down
14 changes: 8 additions & 6 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,8 @@ func (conn *Connection) dial(ctx context.Context) error {

// Subscribe shutdown event to process graceful shutdown.
if conn.shutdownWatcher == nil &&
isFeatureInSlice(WatchersFeature, conn.serverProtocolInfo.Features) {
isFeatureInSlice(iproto.IPROTO_FEATURE_WATCHERS,
conn.serverProtocolInfo.Features) {
watcher, werr := conn.newWatcherImpl(shutdownEventKey, shutdownEventCallback)
if werr != nil {
return werr
Expand Down Expand Up @@ -1425,7 +1426,7 @@ func subscribeWatchChannel(conn *Connection, key string) (chan watchState, error
return st, nil
}

func isFeatureInSlice(expected ProtocolFeature, actualSlice []ProtocolFeature) bool {
func isFeatureInSlice(expected iproto.Feature, actualSlice []iproto.Feature) bool {
for _, actual := range actualSlice {
if expected == actual {
return true
Expand All @@ -1436,8 +1437,8 @@ func isFeatureInSlice(expected ProtocolFeature, actualSlice []ProtocolFeature) b

// NewWatcher creates a new Watcher object for the connection.
//
// You need to require WatchersFeature to use watchers, see examples for the
// function.
// You need to require IPROTO_FEATURE_WATCHERS to use watchers, see examples
// for the function.
//
// After watcher creation, the watcher callback is invoked for the first time.
// In this case, the callback is triggered whether or not the key has already
Expand Down Expand Up @@ -1472,9 +1473,10 @@ func (conn *Connection) NewWatcher(key string, callback WatchCallback) (Watcher,
// asynchronous. We do not expect any response from a Tarantool instance
// That's why we can't just check the Tarantool response for an unsupported
// request error.
if !isFeatureInSlice(WatchersFeature, conn.opts.RequiredProtocolInfo.Features) {
if !isFeatureInSlice(iproto.IPROTO_FEATURE_WATCHERS,
conn.opts.RequiredProtocolInfo.Features) {
err := fmt.Errorf("the feature %s must be required by connection "+
"options to create a watcher", WatchersFeature)
"options to create a watcher", iproto.IPROTO_FEATURE_WATCHERS)
return nil, err
}

Expand Down
7 changes: 4 additions & 3 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/stretchr/testify/require"
"github.com/tarantool/go-iproto"

. "github.com/tarantool/go-tarantool/v2"
)
Expand All @@ -12,20 +13,20 @@ func TestOptsClonePreservesRequiredProtocolFeatures(t *testing.T) {
original := Opts{
RequiredProtocolInfo: ProtocolInfo{
Version: ProtocolVersion(100),
Features: []ProtocolFeature{ProtocolFeature(99), ProtocolFeature(100)},
Features: []iproto.Feature{iproto.Feature(99), iproto.Feature(100)},
},
}

origCopy := original.Clone()

original.RequiredProtocolInfo.Features[1] = ProtocolFeature(98)
original.RequiredProtocolInfo.Features[1] = iproto.Feature(98)

require.Equal(t,
origCopy,
Opts{
RequiredProtocolInfo: ProtocolInfo{
Version: ProtocolVersion(100),
Features: []ProtocolFeature{ProtocolFeature(99), ProtocolFeature(100)},
Features: []iproto.Feature{iproto.Feature(99), iproto.Feature(100)},
},
})
}
9 changes: 5 additions & 4 deletions dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tarantool/go-iproto"

"github.com/tarantool/go-tarantool/v2"
"github.com/tarantool/go-tarantool/v2/test_helpers"
Expand Down Expand Up @@ -72,8 +73,8 @@ func TestDialer_Dial_passedOpts(t *testing.T) {
RequiredProtocol: tarantool.ProtocolInfo{
Auth: tarantool.ChapSha1Auth,
Version: 33,
Features: []tarantool.ProtocolFeature{
tarantool.ErrorExtensionFeature,
Features: []iproto.Feature{
iproto.IPROTO_FEATURE_ERROR_EXTENSION,
},
},
Auth: tarantool.ChapSha1Auth,
Expand Down Expand Up @@ -302,8 +303,8 @@ func TestConn_ProtocolInfo(t *testing.T) {
info := tarantool.ProtocolInfo{
Auth: tarantool.ChapSha1Auth,
Version: 33,
Features: []tarantool.ProtocolFeature{
tarantool.ErrorExtensionFeature,
Features: []iproto.Feature{
iproto.IPROTO_FEATURE_ERROR_EXTENSION,
},
}
conn, dialer := dialIo(t, func(conn *mockIoConn) {
Expand Down
22 changes: 12 additions & 10 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"fmt"
"time"

"github.com/tarantool/go-iproto"

"github.com/tarantool/go-tarantool/v2"
"github.com/tarantool/go-tarantool/v2/test_helpers"
)
Expand Down Expand Up @@ -627,12 +629,12 @@ func ExampleProtocolVersion() {
}
// Output:
// Connector client protocol version: 6
// Connector client protocol feature: StreamsFeature
// Connector client protocol feature: TransactionsFeature
// Connector client protocol feature: ErrorExtensionFeature
// Connector client protocol feature: WatchersFeature
// Connector client protocol feature: PaginationFeature
// Connector client protocol feature: WatchOnceFeature
// Connector client protocol feature: IPROTO_FEATURE_STREAMS
// Connector client protocol feature: IPROTO_FEATURE_TRANSACTIONS
// Connector client protocol feature: IPROTO_FEATURE_ERROR_EXTENSION
// Connector client protocol feature: IPROTO_FEATURE_WATCHERS
// Connector client protocol feature: IPROTO_FEATURE_PAGINATION
// Connector client protocol feature: IPROTO_FEATURE_WATCH_ONCE
}

func getTestTxnOpts() tarantool.Opts {
Expand All @@ -641,9 +643,9 @@ func getTestTxnOpts() tarantool.Opts {
// Assert that server supports expected protocol features
txnOpts.RequiredProtocolInfo = tarantool.ProtocolInfo{
Version: tarantool.ProtocolVersion(1),
Features: []tarantool.ProtocolFeature{
tarantool.StreamsFeature,
tarantool.TransactionsFeature,
Features: []iproto.Feature{
iproto.IPROTO_FEATURE_STREAMS,
iproto.IPROTO_FEATURE_TRANSACTIONS,
},
}

Expand Down Expand Up @@ -1168,7 +1170,7 @@ func ExampleConnection_NewWatcher() {
Pass: "test",
// You need to require the feature to create a watcher.
RequiredProtocolInfo: tarantool.ProtocolInfo{
Features: []tarantool.ProtocolFeature{tarantool.WatchersFeature},
Features: []iproto.Feature{iproto.IPROTO_FEATURE_WATCHERS},
},
}
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
Expand Down
12 changes: 7 additions & 5 deletions pool/connection_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"sync"
"time"

"github.com/tarantool/go-iproto"

"github.com/tarantool/go-tarantool/v2"
)

Expand Down Expand Up @@ -911,8 +913,8 @@ func (p *ConnectionPool) NewPrepared(expr string, userMode Mode) (*tarantool.Pre

// NewWatcher creates a new Watcher object for the connection pool.
//
// You need to require WatchersFeature to use watchers, see examples for the
// function.
// You need to require IPROTO_FEATURE_WATCHERS to use watchers, see examples
// for the function.
//
// The behavior is same as if Connection.NewWatcher() called for each
// connection with a suitable role.
Expand All @@ -932,14 +934,14 @@ func (p *ConnectionPool) NewWatcher(key string,
callback tarantool.WatchCallback, mode Mode) (tarantool.Watcher, error) {
watchersRequired := false
for _, feature := range p.connOpts.RequiredProtocolInfo.Features {
if tarantool.WatchersFeature == feature {
if iproto.IPROTO_FEATURE_WATCHERS == feature {
watchersRequired = true
break
}
}
if !watchersRequired {
return nil, errors.New("the feature WatchersFeature must be " +
"required by connection options to create a watcher")
return nil, errors.New("the feature IPROTO_FEATURE_WATCHERS must " +
"be required by connection options to create a watcher")
}

watcher := &poolWatcher{
Expand Down
27 changes: 14 additions & 13 deletions pool/connection_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tarantool/go-iproto"
"github.com/vmihailenco/msgpack/v5"

"github.com/tarantool/go-tarantool/v2"
Expand Down Expand Up @@ -2832,7 +2833,7 @@ func TestConnectionPool_NewWatcher_noWatchersFeature(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{}
opts.RequiredProtocolInfo.Features = []iproto.Feature{}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")

Expand All @@ -2847,8 +2848,8 @@ func TestConnectionPool_NewWatcher_noWatchersFeature(t *testing.T) {
func(event tarantool.WatchEvent) {}, pool.ANY)
require.Nilf(t, watcher, "watcher must not be created")
require.NotNilf(t, err, "an error is expected")
expected := "the feature WatchersFeature must be required by connection " +
"options to create a watcher"
expected := "the feature IPROTO_FEATURE_WATCHERS must be required by " +
"connection options to create a watcher"
require.Equal(t, expected, err.Error())
}

Expand All @@ -2860,8 +2861,8 @@ func TestConnectionPool_NewWatcher_modes(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")
Expand Down Expand Up @@ -2941,8 +2942,8 @@ func TestConnectionPool_NewWatcher_update(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")
Expand Down Expand Up @@ -3030,8 +3031,8 @@ func TestWatcher_Unregister(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")
Expand Down Expand Up @@ -3091,8 +3092,8 @@ func TestConnectionPool_NewWatcher_concurrent(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")
Expand Down Expand Up @@ -3133,8 +3134,8 @@ func TestWatcher_Unregister_concurrent(t *testing.T) {
roles := []bool{true, false, false, true, true}

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}
err := test_helpers.SetClusterRO(servers, opts, roles)
require.Nilf(t, err, "fail to set roles for cluster")
Expand Down
28 changes: 20 additions & 8 deletions pool/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package pool_test

import (
"fmt"
"strings"
"time"

"github.com/tarantool/go-iproto"

"github.com/tarantool/go-tarantool/v2"
"github.com/tarantool/go-tarantool/v2/pool"
"github.com/tarantool/go-tarantool/v2/test_helpers"
Expand Down Expand Up @@ -92,8 +95,8 @@ func ExampleConnectionPool_NewWatcher() {
const value = "bar"

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{
tarantool.WatchersFeature,
opts.RequiredProtocolInfo.Features = []iproto.Feature{
iproto.IPROTO_FEATURE_WATCHERS,
}

connPool, err := examplePool(testRoles, connOpts)
Expand Down Expand Up @@ -123,7 +126,7 @@ func ExampleConnectionPool_NewWatcher_noWatchersFeature() {
const key = "foo"

opts := connOpts.Clone()
opts.RequiredProtocolInfo.Features = []tarantool.ProtocolFeature{}
opts.RequiredProtocolInfo.Features = []iproto.Feature{}

connPool, err := examplePool(testRoles, connOpts)
if err != nil {
Expand All @@ -134,10 +137,19 @@ func ExampleConnectionPool_NewWatcher_noWatchersFeature() {
callback := func(event tarantool.WatchEvent) {}
watcher, err := connPool.NewWatcher(key, callback, pool.ANY)
fmt.Println(watcher)
fmt.Println(err)
if err != nil {
// Need to split the error message into two lines to pass
// golangci-lint.
str := err.Error()
fmt.Println(strings.Trim(str[:56], " "))
fmt.Println(str[56:])
} else {
fmt.Println(err)
}
// Output:
// <nil>
// the feature WatchersFeature must be required by connection options to create a watcher
// the feature IPROTO_FEATURE_WATCHERS must be required by
// connection options to create a watcher
}

func getTestTxnOpts() tarantool.Opts {
Expand All @@ -146,9 +158,9 @@ func getTestTxnOpts() tarantool.Opts {
// Assert that server supports expected protocol features
txnOpts.RequiredProtocolInfo = tarantool.ProtocolInfo{
Version: tarantool.ProtocolVersion(1),
Features: []tarantool.ProtocolFeature{
tarantool.StreamsFeature,
tarantool.TransactionsFeature,
Features: []iproto.Feature{
iproto.IPROTO_FEATURE_STREAMS,
iproto.IPROTO_FEATURE_TRANSACTIONS,
},
}

Expand Down

0 comments on commit a916922

Please sign in to comment.