Skip to content

Commit

Permalink
refactor: replace connections context with dedicated handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
michal-przytarski committed May 7, 2024
1 parent 22867a8 commit c1a7a70
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 27 deletions.
34 changes: 27 additions & 7 deletions ios/dtx_codec/connection.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dtx

import (
"context"
"errors"
"io"
"math"
"strings"
Expand All @@ -16,6 +16,8 @@ import (

type MethodWithResponse func(msg Message) (interface{}, error)

var ErrConnectionClosed = errors.New("Connection closed")

// Connection manages channels, including the GlobalChannel, for a DtxConnection and dispatches received messages
// to the right channel.
type Connection struct {
Expand All @@ -27,8 +29,9 @@ type Connection struct {
mutex sync.Mutex
requestChannelMessages chan Message

Ctx context.Context
cancelCtx context.CancelCauseFunc
closed chan struct{}
err error
closeOnce sync.Once
}

// Dispatcher is a simple interface containing a Dispatch func to receive dtx.Messages
Expand All @@ -45,14 +48,24 @@ type GlobalDispatcher struct {

const requestChannel = "_requestChannelWithCode:identifier:"

// Closed is closed when the underlying DTX connection was closed for any reason (either initiated by calling Close() or due to an error)
func (dtxConn *Connection) Closed() <-chan struct{} {
return dtxConn.closed
}

// Err is non-nil when the connection was closed (when Close was called this will be ErrConnectionClosed)
func (dtxConn *Connection) Err() error {
return dtxConn.err
}

// Close closes the underlying deviceConnection
func (dtxConn *Connection) Close() error {
if dtxConn.deviceConnection != nil {
err := dtxConn.deviceConnection.Close()
dtxConn.cancelCtx(err)
dtxConn.close(err)
return err
}
dtxConn.cancelCtx(nil)
dtxConn.close(ErrConnectionClosed)
return nil
}

Expand Down Expand Up @@ -128,7 +141,7 @@ func newDtxConnection(conn ios.DeviceConnectionInterface) (*Connection, error) {

// The global channel has channelCode 0, so we need to start with channelCodeCounter==1
dtxConnection := &Connection{deviceConnection: conn, channelCodeCounter: 1, requestChannelMessages: requestChannelMessages}
dtxConnection.Ctx, dtxConnection.cancelCtx = context.WithCancelCause(context.Background())
dtxConnection.closed = make(chan struct{})

// The global channel is automatically present and used for requesting other channels and some other methods like notifyPublishedCapabilities
globalChannel := Channel{
Expand Down Expand Up @@ -157,7 +170,7 @@ func reader(dtxConn *Connection) {
reader := dtxConn.deviceConnection.Reader()
msg, err := ReadMessage(reader)
if err != nil {
defer dtxConn.cancelCtx(err)
defer dtxConn.close(err)
errText := err.Error()
if err == io.EOF || strings.Contains(errText, "use of closed network") {
log.Debug("DTX Connection with EOF")
Expand Down Expand Up @@ -237,3 +250,10 @@ func (dtxConn *Connection) RequestChannelIdentifier(identifier string, messageDi

return channel
}

func (dtxConn *Connection) close(err error) {
dtxConn.closeOnce.Do(func() {
dtxConn.err = err
close(dtxConn.closed)
})
}
14 changes: 8 additions & 6 deletions ios/testmanagerd/xcuitestrunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,14 +384,16 @@ func runXUITestWithBundleIdsXcode15Ctx(
}

select {
case <-conn1.Ctx.Done():
if context.Cause(conn1.Ctx) != nil {
log.WithError(context.Cause(conn1.Ctx)).Error("conn1 ended unexpectedly")
case <-conn1.Closed():
log.Debug("conn1 closed")
if conn1.Err() != dtx.ErrConnectionClosed {
log.WithError(conn1.Err()).Error("conn1 closed unexpectedly")
}
break
case <-conn2.Ctx.Done():
if context.Cause(conn2.Ctx) != nil {
log.WithError(context.Cause(conn2.Ctx)).Error("conn2 ended unexpectedly")
case <-conn2.Closed():
log.Debug("conn2 closed")
if conn2.Err() != dtx.ErrConnectionClosed {
log.WithError(conn2.Err()).Error("conn2 closed unexpectedly")
}
break
case <-testListener.Done():
Expand Down
14 changes: 8 additions & 6 deletions ios/testmanagerd/xcuitestrunner_11.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,16 @@ func runXCUIWithBundleIdsXcode11Ctx(
}

select {
case <-conn.Ctx.Done():
if context.Cause(conn.Ctx) != nil {
log.WithError(context.Cause(conn.Ctx)).Error("conn ended unexpectedly")
case <-conn.Closed():
log.Debug("conn closed")
if conn.Err() != dtx.ErrConnectionClosed {
log.WithError(conn.Err()).Error("conn closed unexpectedly")
}
break
case <-conn2.Ctx.Done():
if context.Cause(conn2.Ctx) != nil {
log.WithError(context.Cause(conn2.Ctx)).Error("conn2 ended unexpectedly")
case <-conn2.Closed():
log.Debug("conn2 closed")
if conn2.Err() != dtx.ErrConnectionClosed {
log.WithError(conn2.Err()).Error("conn2 closed unexpectedly")
}
break
case <-testListener.Done():
Expand Down
16 changes: 8 additions & 8 deletions ios/testmanagerd/xcuitestrunner_12.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,16 @@ func runXUITestWithBundleIdsXcode12Ctx(ctx context.Context, bundleID string, tes
}

select {
case <-conn.Ctx.Done():
log.Info("conn.Ctx.Done()")
if context.Cause(conn.Ctx) != context.Canceled {
log.WithError(context.Cause(conn.Ctx)).Error("conn ended unexpectedly")
case <-conn.Closed():
log.Debug("conn closed")
if conn.Err() != dtx.ErrConnectionClosed {
log.WithError(conn.Err()).Error("conn closed unexpectedly")
}
break
case <-conn2.Ctx.Done():
log.Info("conn2.Ctx.Done()")
if context.Cause(conn2.Ctx) != context.Canceled {
log.WithError(context.Cause(conn2.Ctx)).Error("conn2 ended unexpectedly")
case <-conn2.Closed():
log.Debug("conn2 closed")
if conn2.Err() != dtx.ErrConnectionClosed {
log.WithError(conn2.Err()).Error("conn2 closed unexpectedly")
}
break
case <-testListener.Done():
Expand Down

0 comments on commit c1a7a70

Please sign in to comment.