Skip to content

Commit

Permalink
fix: can choose to stop listening on Ctrl+C
Browse files Browse the repository at this point in the history
  • Loading branch information
sam80180 committed May 4, 2024
1 parent 04a3978 commit 29ca6d9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 93 deletions.
6 changes: 3 additions & 3 deletions cmd/devmode/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ var devmodeEnableCmd = &cobra.Command{
} else {
logrus.Debugf("Device %s is %s.", device.SerialNumber, device.Status)
}
})
}, true)
go (func(cancelFunc *context.CancelFunc) { // timer to cancel listening
time.Sleep(time.Duration(intEnableWaitTimeout) * time.Second)
logrus.Warnf("Timeout waiting for device %s to reboot.", udid)
if cancelFunc != nil {
if cancelFunc != nil && *cancelFunc != nil {
(*cancelFunc)()
}
wg.Done()
Expand All @@ -85,7 +85,7 @@ var devmodeEnableCmd = &cobra.Command{

func initDevModeEnableCmd() {
devmodeRootCMD.AddCommand(devmodeEnableCmd)
devmodeEnableCmd.Flags().StringVarP(&udid, "udid", "u", "", "device's serialNumber")
devmodeEnableCmd.Flags().StringVarP(&udid, "udid", "u", "", "target specific device by UDID")
devmodeEnableCmd.MarkFlagRequired("udid")
devmodeEnableCmd.Flags().BoolVar(&bWaitReboot, "wait", false, "wait for reboot to complete")
devmodeEnableCmd.Flags().IntVar(&intEnableWaitTimeout, "wait-timeout", 60, "wait timeout in seconds")
Expand Down
3 changes: 2 additions & 1 deletion cmd/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var listenCmd = &cobra.Command{
device.SerialNumber = deviceIdMap[device.DeviceID]
delete(deviceIdMap, device.DeviceID)
}
logrus.Debugf("Device %s is %s", device.SerialNumber, device.Status)
if device.Status == "online" {
if isDetail {
detail, err1 := entity.GetDetail(*gidevice)
Expand All @@ -62,7 +63,7 @@ var listenCmd = &cobra.Command{
}
data := util.ResultData(device)
fmt.Println(util.Format(data, isFormat, isDetail))
})
}, true)
wg.Wait()
return nil
},
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/SonicCloudOrg/sonic-gidevice v0.7.7 h1:oWNtc5j0ke/VmDVaXYZOR5JAQ8Cr12Fo1UrMq51lVM4=
github.com/SonicCloudOrg/sonic-gidevice v0.7.7/go.mod h1:SEquP5doc1Xa9Y0556SJBpFg7Pex+jXk+y4XQ4i0yxo=
github.com/SonicCloudOrg/sonic-gidevice v0.7.8 h1:lF8OEuEBIHnqBNq4SGNETwTbUphOrk4OThDPQKrCT3Y=
github.com/SonicCloudOrg/sonic-gidevice v0.7.8/go.mod h1:SEquP5doc1Xa9Y0556SJBpFg7Pex+jXk+y4XQ4i0yxo=
github.com/SonicCloudOrg/sonic-ios-webkit-adapter v0.0.7 h1:s4OTcJ0VG4mg3501Ec+aSR6gQ8eTWz26fdgCUjxlmJQ=
Expand Down
9 changes: 8 additions & 1 deletion src/util/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,17 @@ func (LogrusWriter) Write(data []byte) (int, error) {
if strings.HasSuffix(logmessage, "\n") {
logmessage = logmessage[:len(logmessage)-1]
}
if logmessage == "handle_events: error: libusb: interrupted [code -10]" { // handle this annoying message
if logmessage == "handle_events: error: libusb: interrupted [code -10]" {
logrus.Debug(logmessage)
} else {
fmt.Printf("%s", string(data))
}
return len(logmessage), nil
}

func GetGoRoutineLogger(name string) *logrus.Entry {
return logrus.WithFields(logrus.Fields{
"goroutine": GoRoutineID(),
"goroutineName": name,
})
}
166 changes: 80 additions & 86 deletions src/util/usbmux.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,24 @@ import (
"time"

giDevice "github.com/SonicCloudOrg/sonic-gidevice"
"github.com/SonicCloudOrg/sonic-gidevice/pkg/libimobiledevice"
"github.com/SonicCloudOrg/sonic-ios-bridge/src/entity"
"github.com/cenkalti/backoff/v4"
"github.com/quintans/toolkit/latch"
"github.com/sirupsen/logrus"
)

func UsbmuxListen(cbOnData func(gidevice *giDevice.Device, device *entity.Device, e error, cancelFunc context.CancelFunc)) context.CancelFunc {
usbmuxInput := make(chan giDevice.Device)
type UsbmuxListenCallback func(gidevice *giDevice.Device, device *entity.Device, e error, cancelFunc context.CancelFunc)

func UsbmuxListen(cbOnData UsbmuxListenCallback, bExitOnCtrlC bool) context.CancelFunc {
sigTerm := make(chan os.Signal, 1)
signal.Notify(sigTerm, os.Interrupt, os.Kill)
var funcCancelListen context.CancelFunc
healthCheck := make(chan bool)
mylatch := latch.NewCountDownLatch()
mylatch.Add(2)
mylatch.Add(1)
go (func() {
goroutineId := GoRoutineID()
logger := logrus.WithFields(logrus.Fields{
"goroutine": goroutineId,
"goroutineName": "healthCheck",
})
backoffAlgorithm := backoff.NewConstantBackOff(30 * time.Second)
logger := GetGoRoutineLogger("healthCheck")
backoffAlgorithm := backoff.NewConstantBackOff(10 * time.Second)
bIsOk := true
backoff.RetryNotify(func() error {
if mylatch.Counter() <= 0 {
Expand All @@ -40,7 +36,7 @@ func UsbmuxListen(cbOnData func(gidevice *giDevice.Device, device *entity.Device
logger.Debug("Connecting to usbmux...")
usbMuxClient, err := giDevice.NewUsbmux()
if err != nil {
return NewErrorPrint(ErrConnect, "usbMux", err)
return err
}
for {
if mylatch.Counter() <= 0 {
Expand All @@ -66,102 +62,100 @@ func UsbmuxListen(cbOnData func(gidevice *giDevice.Device, device *entity.Device
logger.Trace("end health check")
})()
go (func(funcStop *context.CancelFunc) {
goroutineId := GoRoutineID()
logger := logrus.WithFields(logrus.Fields{
"goroutine": goroutineId,
"goroutineName": "usbmuxListen",
})
backoffAlgorithm := backoff.NewConstantBackOff(30 * time.Second)
logger := GetGoRoutineLogger("signalHandler")
for range sigTerm {
logger.Debugf("Stop listening by signal")
if funcStop != nil && *funcStop != nil {
(*funcStop)()
}
if bExitOnCtrlC {
os.Exit(128 + int(syscall.SIGTERM)) // https://itsfoss.com/linux-exit-codes/#code-143-or-sigterm
}
}
})(&funcCancelListen)
go (func(funcStop *context.CancelFunc) {
logger := GetGoRoutineLogger("usbmuxListen")
backoffAlgorithm := backoff.NewConstantBackOff(10 * time.Second)
bIsOk := true
backoff.RetryNotify(func() error {
if mylatch.Counter() <= 1 { // 'read channel input' go routine is stopped
return nil
}
logger.Debug("Connecting to usbmux...")
usbMuxClient, err := giDevice.NewUsbmux()
if err != nil {
return NewErrorPrint(ErrConnect, "usbMux", err)
return err
}
usbmuxInput := make(chan giDevice.Device)
shutDownFun, errListen := usbMuxClient.Listen(usbmuxInput)
(*funcStop) = shutDownFun
*funcStop = func() {
logrus.Debugf("Call usbmux listen shutdown function")
mylatch.Done()
if shutDownFun != nil {
shutDownFun()
}
}
if errListen != nil {
return NewErrorPrint(ErrSendCommand, string(libimobiledevice.MessageTypeListen), errListen)
return errListen
}
logger.Info("Start listening...")
<-healthCheck // empty out the channel
if !bIsOk { // transition from not OK to OK
if !bIsOk { // transition from not OK to OK
logger.Trace("Reset usbmux listen backoff algorithm")
backoffAlgorithm.Reset()
bIsOk = true
}
for range healthCheck {
logger.Info("Cancel listening")
(*funcStop) = nil
return fmt.Errorf("usbmux listening is cancelled")
logger.Debugf("Start listening...")
numOnlineDevices := 0
loopRead:
for {
select {
case bIsUnhealthy := <-healthCheck:
if bIsUnhealthy {
logger.Info("Cancel listening because usbmuxd is unhealthy")
return fmt.Errorf("usbmux listening is cancelled")
}
case d, ok := <-usbmuxInput:
if !ok { // channel is closed
logger.Info("usbmux input channel is closed")
if mylatch.Counter() > 0 {
return fmt.Errorf("usbmux listening stopped unexpectedly")
}
break loopRead
}
if d == nil {
continue
}
deviceByte, _ := json.Marshal(d.Properties())
var device entity.Device
errDec := json.Unmarshal(deviceByte, &device)
var ptrEntityDevice *entity.Device = &device
if errDec == nil {
device.Status = device.GetStatus()
if device.Status == "online" {
numOnlineDevices += 1
} else {
numOnlineDevices -= 1
}
} else {
ptrEntityDevice = nil
}
var _fStop context.CancelFunc
if funcStop != nil {
_fStop = *funcStop
}
if cbOnData != nil {
cbOnData(&d, ptrEntityDevice, errDec, _fStop)
}
logger.Debugf("Number of online devices= %d", numOnlineDevices)
if numOnlineDevices <= 0 {
logger.Info("No devices are online")
}
}
}
return nil
}, backoffAlgorithm, func(err error, d time.Duration) {
bIsOk = false
logger.Warnf("usbmux listening error: %+v", err)
logger.Debugf("next retry listening in %s", d.String())
logger.Debugf("Next retry listening in %s", d.String())
})
mylatch.Done()
logger.Trace("end usbmux listen")
})(&funcCancelListen)
go (func(funcStop *context.CancelFunc) {
goroutineId := GoRoutineID()
logger := logrus.WithFields(logrus.Fields{
"goroutine": goroutineId,
"goroutineName": "loopRead",
})
numOnlineDevices := 0
loopRead:
for {
select {
case d, ok := <-usbmuxInput:
if !ok { // channel is closed
logger.Info("usbmux input channel is closed")
break loopRead
}
if d == nil {
continue
}
deviceByte, _ := json.Marshal(d.Properties())
var device entity.Device
errDec := json.Unmarshal(deviceByte, &device)
var ptrEntityDevice *entity.Device = &device
if errDec == nil {
device.Status = device.GetStatus()
if device.Status == "online" {
numOnlineDevices += 1
} else {
numOnlineDevices -= 1
}
} else {
ptrEntityDevice = nil
}
var _fStop context.CancelFunc
if funcStop != nil {
_fStop = *funcStop
}
if cbOnData != nil {
cbOnData(&d, ptrEntityDevice, errDec, _fStop)
}
logger.Debugf("Number of online devices= %d", numOnlineDevices)
if numOnlineDevices <= 0 {
logger.Info("No devices are online")
}
case <-sigTerm:
logger.Info("Stop listening")
if funcStop != nil {
(*funcStop)()
}
os.Exit(128 + int(syscall.SIGTERM)) // https://itsfoss.com/linux-exit-codes/#code-143-or-sigterm
break loopRead
}
}
mylatch.Done()
logger.Trace("end reading channel input")
})(&funcCancelListen)
return funcCancelListen
}

0 comments on commit 29ca6d9

Please sign in to comment.