Skip to content

Commit 0bdd2e7

Browse files
committed
connection: make dialer mandatory
This patch modifies `Connect` api. Now, to connect to the Tarantool, you need to pass an object that satisfies `tarantool.Dialer` interface. You can use one of the existing implementations: `TtDialer` or `OpenSslDialer`. For example: ``` conn, err := tarantool.Connect(context.Background(), tarantool.TtDialer{ Address: "127.0.0.1:3301", User: "user", Password: "secret", }, tarantool.Opts{}) ``` To create a connection pool, you need to pass a `map[string]tarantool.Dialer`, where each dialer is associated with a unique ID (for example, it can be the server address). Connections will be distinguished from each other using these IDs. For example: ``` connPool, err := pool.Connect(context.Background(), map[string]tarantool.Dialer{ "127.0.0.1": tarantool.TtDialer{ Address: "127.0.0.1", User: "user", Password: "secret", }, }, tarantool.Opts{}) ``` The `conn.RemoteAddr` and `conn.LocalAddr` functions have been removed. To obtain the connection address, you can use `conn.Addr`. This function panics if the connection has not been established. Now, `NewWatcher` checks the actual features of the server, rather than relying on the features provided by the user during connection creation. In the case of connection pool, watchers are created for connections that support this feature. `ClientProtocolInfo`, `ServerProtocolInfo` were removed. Now, there is `ProtocolInfo`, which returns the server protocol info. Part of #321
1 parent c564e6d commit 0bdd2e7

File tree

7 files changed

+476
-449
lines changed

7 files changed

+476
-449
lines changed

connection.go

+23-128
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"log"
1212
"math"
13+
"net"
1314
"runtime"
1415
"sync"
1516
"sync/atomic"
@@ -89,16 +90,14 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
8990
case LogReconnectFailed:
9091
reconnects := v[0].(uint)
9192
err := v[1].(error)
92-
log.Printf("tarantool: reconnect (%d/%d) to %s failed: %s",
93-
reconnects, conn.opts.MaxReconnects, conn.addr, err)
93+
log.Printf("tarantool: reconnect (%d/%d) failed: %s",
94+
reconnects, conn.opts.MaxReconnects, err)
9495
case LogLastReconnectFailed:
9596
err := v[0].(error)
96-
log.Printf("tarantool: last reconnect to %s failed: %s, giving it up",
97-
conn.addr, err)
97+
log.Printf("tarantool: last reconnect failed: %s, giving it up", err)
9898
case LogUnexpectedResultId:
9999
resp := v[0].(*Response)
100-
log.Printf("tarantool: connection %s got unexpected resultId (%d) in response",
101-
conn.addr, resp.RequestId)
100+
log.Printf("tarantool: got unexpected resultId (%d) in response", resp.RequestId)
102101
case LogWatchEventReadFailed:
103102
err := v[0].(error)
104103
log.Printf("tarantool: unable to parse watch event: %s", err)
@@ -156,10 +155,10 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
156155
// More on graceful shutdown:
157156
// https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/graceful_shutdown/
158157
type Connection struct {
159-
addr string
160-
c Conn
161-
mutex sync.Mutex
162-
cond *sync.Cond
158+
dialer Dialer
159+
c Conn
160+
mutex sync.Mutex
161+
cond *sync.Cond
163162
// Schema contains schema loaded on connection.
164163
Schema *Schema
165164
// requestId contains the last request ID for requests with nil context.
@@ -260,11 +259,6 @@ const (
260259

261260
// Opts is a way to configure Connection
262261
type Opts struct {
263-
// Auth is an authentication method.
264-
Auth Auth
265-
// Dialer is a Dialer object used to create a new connection to a
266-
// Tarantool instance. TtDialer is a default one.
267-
Dialer Dialer
268262
// Timeout for response to a particular request. The timeout is reset when
269263
// push messages are received. If Timeout is zero, any request can be
270264
// blocked infinitely.
@@ -287,10 +281,6 @@ type Opts struct {
287281
// endlessly.
288282
// After MaxReconnects attempts Connection becomes closed.
289283
MaxReconnects uint
290-
// Username for logging in to Tarantool.
291-
User string
292-
// User password for logging in to Tarantool.
293-
Pass string
294284
// RateLimit limits number of 'in-fly' request, i.e. already put into
295285
// requests queue, but not yet answered by server or timeouted.
296286
// It is disabled by default.
@@ -315,83 +305,23 @@ type Opts struct {
315305
Handle interface{}
316306
// Logger is user specified logger used for error messages.
317307
Logger Logger
318-
// Transport is the connection type, by default the connection is unencrypted.
319-
Transport string
320-
// SslOpts is used only if the Transport == 'ssl' is set.
321-
Ssl SslOpts
322-
// RequiredProtocolInfo contains minimal protocol version and
323-
// list of protocol features that should be supported by
324-
// Tarantool server. By default there are no restrictions.
325-
RequiredProtocolInfo ProtocolInfo
326-
}
327-
328-
// SslOpts is a way to configure ssl transport.
329-
type SslOpts struct {
330-
// KeyFile is a path to a private SSL key file.
331-
KeyFile string
332-
// CertFile is a path to an SSL certificate file.
333-
CertFile string
334-
// CaFile is a path to a trusted certificate authorities (CA) file.
335-
CaFile string
336-
// Ciphers is a colon-separated (:) list of SSL cipher suites the connection
337-
// can use.
338-
//
339-
// We don't provide a list of supported ciphers. This is what OpenSSL
340-
// does. The only limitation is usage of TLSv1.2 (because other protocol
341-
// versions don't seem to support the GOST cipher). To add additional
342-
// ciphers (GOST cipher), you must configure OpenSSL.
343-
//
344-
// See also
345-
//
346-
// * https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
347-
Ciphers string
348-
// Password is a password for decrypting the private SSL key file.
349-
// The priority is as follows: try to decrypt with Password, then
350-
// try PasswordFile.
351-
Password string
352-
// PasswordFile is a path to the list of passwords for decrypting
353-
// the private SSL key file. The connection tries every line from the
354-
// file as a password.
355-
PasswordFile string
356-
}
357-
358-
// Clone returns a copy of the Opts object.
359-
// Any changes in copy RequiredProtocolInfo will not affect the original
360-
// RequiredProtocolInfo value.
361-
func (opts Opts) Clone() Opts {
362-
optsCopy := opts
363-
optsCopy.RequiredProtocolInfo = opts.RequiredProtocolInfo.Clone()
364-
365-
return optsCopy
366308
}
367309

368310
// Connect creates and configures a new Connection.
369-
//
370-
// Address could be specified in following ways:
371-
//
372-
// - TCP connections (tcp://192.168.1.1:3013, tcp://my.host:3013,
373-
// tcp:192.168.1.1:3013, tcp:my.host:3013, 192.168.1.1:3013, my.host:3013)
374-
//
375-
// - Unix socket, first '/' or '.' indicates Unix socket
376-
// (unix:///abs/path/tnt.sock, unix:path/tnt.sock, /abs/path/tnt.sock,
377-
// ./rel/path/tnt.sock, unix/:path/tnt.sock)
378-
func Connect(ctx context.Context, addr string, opts Opts) (conn *Connection, err error) {
311+
func Connect(ctx context.Context, dialer Dialer, opts Opts) (conn *Connection, err error) {
379312
conn = &Connection{
380-
addr: addr,
313+
dialer: dialer,
381314
requestId: 0,
382315
contextRequestId: 1,
383316
Greeting: &Greeting{},
384317
control: make(chan struct{}),
385-
opts: opts.Clone(),
318+
opts: opts,
386319
dec: msgpack.NewDecoder(&smallBuf{}),
387320
}
388321
maxprocs := uint32(runtime.GOMAXPROCS(-1))
389322
if conn.opts.Concurrency == 0 || conn.opts.Concurrency > maxprocs*128 {
390323
conn.opts.Concurrency = maxprocs * 4
391324
}
392-
if conn.opts.Dialer == nil {
393-
conn.opts.Dialer = TtDialer{}
394-
}
395325
if c := conn.opts.Concurrency; c&(c-1) != 0 {
396326
for i := uint(1); i < 32; i *= 2 {
397327
c |= c >> i
@@ -472,28 +402,9 @@ func (conn *Connection) CloseGraceful() error {
472402
}
473403

474404
// Addr returns a configured address of Tarantool socket.
475-
func (conn *Connection) Addr() string {
476-
return conn.addr
477-
}
478-
479-
// RemoteAddr returns an address of Tarantool socket.
480-
func (conn *Connection) RemoteAddr() string {
481-
conn.mutex.Lock()
482-
defer conn.mutex.Unlock()
483-
if conn.c == nil {
484-
return ""
485-
}
486-
return conn.c.RemoteAddr().String()
487-
}
488-
489-
// LocalAddr returns an address of outgoing socket.
490-
func (conn *Connection) LocalAddr() string {
491-
conn.mutex.Lock()
492-
defer conn.mutex.Unlock()
493-
if conn.c == nil {
494-
return ""
495-
}
496-
return conn.c.LocalAddr().String()
405+
// It panics, if the connection has not been successfully established.
406+
func (conn *Connection) Addr() net.Addr {
407+
return conn.c.Addr()
497408
}
498409

499410
// Handle returns a user-specified handle from Opts.
@@ -512,14 +423,8 @@ func (conn *Connection) dial(ctx context.Context) error {
512423
opts := conn.opts
513424

514425
var c Conn
515-
c, err := conn.opts.Dialer.Dial(ctx, conn.addr, DialOpts{
516-
IoTimeout: opts.Timeout,
517-
Transport: opts.Transport,
518-
Ssl: opts.Ssl,
519-
RequiredProtocol: opts.RequiredProtocolInfo,
520-
Auth: opts.Auth,
521-
User: opts.User,
522-
Password: opts.Pass,
426+
c, err := conn.dialer.Dial(ctx, DialOpts{
427+
IoTimeout: opts.Timeout,
523428
})
524429
if err != nil {
525430
return err
@@ -1437,8 +1342,7 @@ func isFeatureInSlice(expected iproto.Feature, actualSlice []iproto.Feature) boo
14371342

14381343
// NewWatcher creates a new Watcher object for the connection.
14391344
//
1440-
// You need to require IPROTO_FEATURE_WATCHERS to use watchers, see examples
1441-
// for the function.
1345+
// Server must support IPROTO_FEATURE_WATCHERS to use watchers.
14421346
//
14431347
// After watcher creation, the watcher callback is invoked for the first time.
14441348
// In this case, the callback is triggered whether or not the key has already
@@ -1474,9 +1378,9 @@ func (conn *Connection) NewWatcher(key string, callback WatchCallback) (Watcher,
14741378
// That's why we can't just check the Tarantool response for an unsupported
14751379
// request error.
14761380
if !isFeatureInSlice(iproto.IPROTO_FEATURE_WATCHERS,
1477-
conn.opts.RequiredProtocolInfo.Features) {
1478-
err := fmt.Errorf("the feature %s must be required by connection "+
1479-
"options to create a watcher", iproto.IPROTO_FEATURE_WATCHERS)
1381+
conn.c.ProtocolInfo().Features) {
1382+
err := fmt.Errorf("the feature %s must be supported by connection "+
1383+
"to create a watcher", iproto.IPROTO_FEATURE_WATCHERS)
14801384
return nil, err
14811385
}
14821386

@@ -1567,23 +1471,14 @@ func (conn *Connection) newWatcherImpl(key string, callback WatchCallback) (Watc
15671471
}, nil
15681472
}
15691473

1570-
// ServerProtocolVersion returns protocol version and protocol features
1474+
// ProtocolInfo returns protocol version and protocol features
15711475
// supported by connected Tarantool server. Beware that values might be
15721476
// outdated if connection is in a disconnected state.
15731477
// Since 1.10.0
1574-
func (conn *Connection) ServerProtocolInfo() ProtocolInfo {
1478+
func (conn *Connection) ProtocolInfo() ProtocolInfo {
15751479
return conn.serverProtocolInfo.Clone()
15761480
}
15771481

1578-
// ClientProtocolVersion returns protocol version and protocol features
1579-
// supported by Go connection client.
1580-
// Since 1.10.0
1581-
func (conn *Connection) ClientProtocolInfo() ProtocolInfo {
1582-
info := clientProtocolInfo.Clone()
1583-
info.Auth = conn.opts.Auth
1584-
return info
1585-
}
1586-
15871482
func shutdownEventCallback(event WatchEvent) {
15881483
// Receives "true" on server shutdown.
15891484
// See https://www.tarantool.io/en/doc/latest/dev_guide/internals/iproto/graceful_shutdown/

0 commit comments

Comments
 (0)