Skip to content

Commit d569373

Browse files
committed
Set deadline for tcp connection
This sets up tcp connection deadline for write and read requests to fail after timeout instead of blocking for a long time in case of accidental disconnection of the ovsdb leader. Signed-off-by: Periyasamy Palanisamy <[email protected]>
1 parent cf04722 commit d569373

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

client/client.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ type ovsdbClient struct {
8787
metrics metrics
8888
connected bool
8989
rpcClient *rpc2.Client
90+
conn net.Conn
9091
rpcMutex sync.RWMutex
9192
// endpoints contains all possible endpoints; the first element is
9293
// the active endpoint if connected=true
@@ -427,6 +428,7 @@ func (o *ovsdbClient) createRPC2Client(conn net.Conn) {
427428
if o.options.inactivityTimeout > 0 {
428429
o.trafficSeen = make(chan struct{})
429430
}
431+
o.conn = conn
430432
o.rpcClient = rpc2.NewClientWithCodec(jsonrpc.NewJSONCodec(conn))
431433
o.rpcClient.SetBlocking(true)
432434
o.rpcClient.Handle("echo", func(_ *rpc2.Client, args []interface{}, reply *[]interface{}) error {
@@ -748,7 +750,7 @@ func (o *ovsdbClient) update3(params []json.RawMessage, reply *[]interface{}) er
748750
func (o *ovsdbClient) getSchema(ctx context.Context, dbName string) (ovsdb.DatabaseSchema, error) {
749751
args := ovsdb.NewGetSchemaArgs(dbName)
750752
var reply ovsdb.DatabaseSchema
751-
err := o.rpcClient.CallWithContext(ctx, "get_schema", args, &reply)
753+
err := o.CallWithContext(ctx, "get_schema", args, &reply)
752754
if err != nil {
753755
if err == rpc2.ErrShutdown {
754756
return ovsdb.DatabaseSchema{}, ErrNotConnected
@@ -763,7 +765,7 @@ func (o *ovsdbClient) getSchema(ctx context.Context, dbName string) (ovsdb.Datab
763765
// Should only be called when mutex is held
764766
func (o *ovsdbClient) listDbs(ctx context.Context) ([]string, error) {
765767
var dbs []string
766-
err := o.rpcClient.CallWithContext(ctx, "list_dbs", nil, &dbs)
768+
err := o.CallWithContext(ctx, "list_dbs", nil, &dbs)
767769
if err != nil {
768770
if err == rpc2.ErrShutdown {
769771
return nil, ErrNotConnected
@@ -836,7 +838,7 @@ func (o *ovsdbClient) transact(ctx context.Context, dbName string, skipChWrite b
836838
if dbgLogger.Enabled() {
837839
dbgLogger.Info("transacting operations", "operations", fmt.Sprintf("%+v", operation))
838840
}
839-
err := o.rpcClient.CallWithContext(ctx, "transact", args, &reply)
841+
err := o.CallWithContext(ctx, "transact", args, &reply)
840842
if err != nil {
841843
if err == rpc2.ErrShutdown {
842844
return nil, ErrNotConnected
@@ -869,7 +871,7 @@ func (o *ovsdbClient) MonitorCancel(ctx context.Context, cookie MonitorCookie) e
869871
if o.rpcClient == nil {
870872
return ErrNotConnected
871873
}
872-
err := o.rpcClient.CallWithContext(ctx, "monitor_cancel", args, &reply)
874+
err := o.CallWithContext(ctx, "monitor_cancel", args, &reply)
873875
if err != nil {
874876
if err == rpc2.ErrShutdown {
875877
return ErrNotConnected
@@ -981,15 +983,15 @@ func (o *ovsdbClient) monitor(ctx context.Context, cookie MonitorCookie, reconne
981983
switch monitor.Method {
982984
case ovsdb.MonitorRPC:
983985
var reply ovsdb.TableUpdates
984-
err = o.rpcClient.CallWithContext(ctx, monitor.Method, args, &reply)
986+
err = o.CallWithContext(ctx, monitor.Method, args, &reply)
985987
tableUpdates = reply
986988
case ovsdb.ConditionalMonitorRPC:
987989
var reply ovsdb.TableUpdates2
988-
err = o.rpcClient.CallWithContext(ctx, monitor.Method, args, &reply)
990+
err = o.CallWithContext(ctx, monitor.Method, args, &reply)
989991
tableUpdates = reply
990992
case ovsdb.ConditionalMonitorSinceRPC:
991993
var reply ovsdb.MonitorCondSinceReply
992-
err = o.rpcClient.CallWithContext(ctx, monitor.Method, args, &reply)
994+
err = o.CallWithContext(ctx, monitor.Method, args, &reply)
993995
if err == nil && reply.Found {
994996
monitor.LastTransactionID = reply.LastTransactionID
995997
lastTransactionFound = true
@@ -1080,7 +1082,7 @@ func (o *ovsdbClient) Echo(ctx context.Context) error {
10801082
if o.rpcClient == nil {
10811083
return ErrNotConnected
10821084
}
1083-
err := o.rpcClient.CallWithContext(ctx, "echo", args, &reply)
1085+
err := o.CallWithContext(ctx, "echo", args, &reply)
10841086
if err != nil {
10851087
if err == rpc2.ErrShutdown {
10861088
return ErrNotConnected
@@ -1439,3 +1441,20 @@ func (o *ovsdbClient) WhereAll(m model.Model, conditions ...model.Condition) Con
14391441
func (o *ovsdbClient) WhereCache(predicate interface{}) ConditionalAPI {
14401442
return o.primaryDB().api.WhereCache(predicate)
14411443
}
1444+
1445+
// CallWithContext invokes the named function, waits for it to complete, and
1446+
// returns its error status, or an error from Context timeout.
1447+
func (o *ovsdbClient) CallWithContext(ctx context.Context, method string, args interface{}, reply interface{}) error {
1448+
// Set up read/write deadline for tcp connection before making
1449+
// a rpc request to the server.
1450+
if reflect.TypeOf(o.conn).String() == "*net.TCPConn" {
1451+
tcpConn := o.conn.(*net.TCPConn)
1452+
if o.options.timeout > 0 {
1453+
err := tcpConn.SetDeadline(time.Now().Add(o.options.timeout * 3))
1454+
if err != nil {
1455+
return err
1456+
}
1457+
}
1458+
}
1459+
return o.rpcClient.CallWithContext(ctx, method, args, reply)
1460+
}

0 commit comments

Comments
 (0)