Skip to content

Commit

Permalink
Make transactions block when using WithReconnect
Browse files Browse the repository at this point in the history
When creating a client using WithReconnect any requested Transact method
will block if the client is currently disconnected, and wait until it is
reconnected to execute the transaction (within a given context).

Signed-off-by: Tim Rozet <trozet@redhat.com>
  • Loading branch information
trozet committed Nov 5, 2021
1 parent 34a572b commit d33a5ef
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
25 changes: 23 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,31 @@ func (o *ovsdbClient) listDbs(ctx context.Context) ([]string, error) {
// RFC 7047 : transact
func (o *ovsdbClient) Transact(ctx context.Context, operation ...ovsdb.Operation) ([]ovsdb.OperationResult, error) {
o.rpcMutex.Lock()
defer o.rpcMutex.Unlock()
if o.rpcClient == nil {
return nil, ErrNotConnected
o.rpcMutex.Unlock()
if o.options.reconnect {
o.logger.V(5).Info("blocking transaction until reconnected", "operations",
fmt.Sprintf("%+v", operation))
ticker := time.NewTicker(50 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return nil, fmt.Errorf("%w: while awaiting reconnection", ctx.Err())
case <-ticker.C:
o.rpcMutex.Lock()
if o.rpcClient != nil {
break
}
o.rpcMutex.Unlock()
}
}
} else {
return nil, ErrNotConnected
}
}
defer o.rpcMutex.Unlock()

return o.transact(ctx, o.primaryDBName, operation...)
}

Expand Down
4 changes: 3 additions & 1 deletion client/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ func WithLeaderOnly(leaderOnly bool) Option {
// WithReconnect tells the client to automatically reconnect when
// disconnected. The timeout is used to construct the context on
// each call to Connect, while backoff dictates the backoff
// algorithm to use
// algorithm to use. Using WithReconnect implies that
// requested transactions will block until the client has fully reconnected,
// rather than immediately returning an error if there is no connection.
func WithReconnect(timeout time.Duration, backoff backoff.BackOff) Option {
return func(o *options) error {
o.reconnect = true
Expand Down

0 comments on commit d33a5ef

Please sign in to comment.