@@ -5,6 +5,7 @@ package tarantool
5
5
import (
6
6
"bufio"
7
7
"bytes"
8
+ "context"
8
9
"errors"
9
10
"fmt"
10
11
"io"
@@ -139,6 +140,8 @@ type Connection struct {
139
140
state uint32
140
141
dec * msgpack.Decoder
141
142
lenbuf [PacketLengthBytes ]byte
143
+
144
+ futCanceler futureCanceler
142
145
}
143
146
144
147
var _ = Connector (& Connection {}) // Check compatibility with connector interface.
@@ -334,6 +337,7 @@ func Connect(addr string, opts Opts) (conn *Connection, err error) {
334
337
return nil , err
335
338
}
336
339
}
340
+ conn .futCanceler = newFutCancelerImpl (conn .cancelFuture )
337
341
338
342
return conn , err
339
343
}
@@ -387,6 +391,16 @@ func (conn *Connection) Handle() interface{} {
387
391
return conn .opts .Handle
388
392
}
389
393
394
+ // cancelFuture removes the passed future from the internal queue of Future objects.
395
+ func (conn * Connection ) cancelFuture (fut * Future , err error ) error {
396
+ if fut == nil {
397
+ return fmt .Errorf ("passed nil future" )
398
+ }
399
+ fut .SetError (err )
400
+ conn .fetchFuture (fut .requestId )
401
+ return nil
402
+ }
403
+
390
404
func (conn * Connection ) dial () (err error ) {
391
405
var connection net.Conn
392
406
network := "tcp"
@@ -721,8 +735,8 @@ func (conn *Connection) reader(r *bufio.Reader, c net.Conn) {
721
735
}
722
736
}
723
737
724
- func (conn * Connection ) newFuture () (fut * Future ) {
725
- fut = NewFuture ()
738
+ func (conn * Connection ) newFuture (ctx context. Context ) (fut * Future ) {
739
+ fut = NewFuture (ctx , conn . futCanceler )
726
740
if conn .rlimit != nil && conn .opts .RLimitAction == RLimitDrop {
727
741
select {
728
742
case conn .rlimit <- struct {}{}:
@@ -785,8 +799,8 @@ func (conn *Connection) newFuture() (fut *Future) {
785
799
return
786
800
}
787
801
788
- func (conn * Connection ) send (req Request ) * Future {
789
- fut := conn .newFuture ()
802
+ func (conn * Connection ) send (ctx context. Context , req Request ) * Future {
803
+ fut := conn .newFuture (ctx )
790
804
if fut .ready == nil {
791
805
return fut
792
806
}
@@ -992,26 +1006,34 @@ func (conn *Connection) nextRequestId() (requestId uint32) {
992
1006
//
993
1007
// An error is returned if the request was formed incorrectly, or failure to
994
1008
// communicate by the connection, or unable to decode the response.
995
- func (conn * Connection ) Do (req Request ) (* Response , error ) {
996
- fut := conn .DoAsync (req )
1009
+ func (conn * Connection ) Do (ctx context. Context , req Request ) (* Response , error ) {
1010
+ fut := conn .DoAsync (ctx , req )
997
1011
return fut .Get ()
998
1012
}
999
1013
1000
1014
// DoTyped verifies, sends the request and fills the typed result.
1001
1015
//
1002
1016
// An error is returned if the request was formed incorrectly, or failure to
1003
1017
// communicate by the connection, or unable to decode the response.
1004
- func (conn * Connection ) DoTyped (req Request , result interface {}) error {
1005
- fut := conn .DoAsync (req )
1018
+ func (conn * Connection ) DoTyped (ctx context. Context , req Request , result interface {}) error {
1019
+ fut := conn .DoAsync (ctx , req )
1006
1020
return fut .GetTyped (result )
1007
1021
}
1008
1022
1009
1023
// DoAsync verifies, sends the request and returns a future.
1010
1024
//
1011
1025
// An error is returned if the request was formed incorrectly, or failure to
1012
1026
// create the future.
1013
- func (conn * Connection ) DoAsync (req Request ) * Future {
1014
- return conn .send (req )
1027
+ func (conn * Connection ) DoAsync (ctx context.Context , req Request ) * Future {
1028
+ if ctx == nil {
1029
+ return NewErrorFuture (errors .New ("passed nil context" ))
1030
+ }
1031
+ select {
1032
+ case <- ctx .Done ():
1033
+ return NewErrorFuture (errors .New ("context is done" ))
1034
+ default :
1035
+ }
1036
+ return conn .send (ctx , req )
1015
1037
}
1016
1038
1017
1039
// ConfiguredTimeout returns a timeout from connection config.
0 commit comments