diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index f12c09f..6a4f345 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -5,6 +5,7 @@ import ( "cwtch.im/cwtch/protocol/connections" "git.openprivacy.ca/openprivacy/log" "math" + "strconv" "sync" "time" ) @@ -113,6 +114,7 @@ type contactRetry struct { breakChan chan bool onion string lastCheck time.Time + acnProgress int connections sync.Map //[string]*contact connCount int @@ -249,8 +251,6 @@ func (cr *contactRetry) run() { } } } - case event.ProtocolEngineCreated: - cr.protocolEngine = true case event.ProtocolEngineShutdown: cr.ACNUp = false @@ -265,22 +265,15 @@ func (cr *contactRetry) run() { p.failedCount = 0 return true }) + case event.ProtocolEngineCreated: + cr.protocolEngine = true + cr.processStatus() case event.ACNStatus: - prog := e.Data[event.Progress] - if !cr.protocolEngine { - continue - } - if prog == "100" && !cr.ACNUp { - cr.ACNUp = true - cr.ACNUpTime = time.Now() - cr.connections.Range(func(k, v interface{}) bool { - p := v.(*contact) - p.failedCount = 0 - return true - }) - } else if prog != "100" { - cr.ACNUp = false + progData := e.Data[event.Progress] + if prog, err := strconv.Atoi(progData); err == nil { + cr.acnProgress = prog + cr.processStatus() } } @@ -294,6 +287,24 @@ func (cr *contactRetry) run() { } } +func (cr *contactRetry) processStatus() { + if !cr.protocolEngine { + cr.ACNUp = false + return + } + if cr.acnProgress == 100 && !cr.ACNUp { + cr.ACNUp = true + cr.ACNUpTime = time.Now() + cr.connections.Range(func(k, v interface{}) bool { + p := v.(*contact) + p.failedCount = 0 + return true + }) + } else if cr.acnProgress != 100 { + cr.ACNUp = false + } +} + func (cr *contactRetry) requeueReady() { if !cr.ACNUp { return diff --git a/protocol/connections/engine.go b/protocol/connections/engine.go index 9cd0872..a264f47 100644 --- a/protocol/connections/engine.go +++ b/protocol/connections/engine.go @@ -342,18 +342,20 @@ func (e *engine) Shutdown() { // don't accept any more events... e.queue.Publish(event.NewEvent(event.ProtocolEngineShutdown, map[event.Field]string{})) e.service.Shutdown() - e.shuttingDown.Store(true) - e.ephemeralServicesLock.Lock() defer e.ephemeralServicesLock.Unlock() for _, connection := range e.ephemeralServices { log.Infof("shutting down ephemeral service") - connection.connectingLock.Lock() - connection.service.Shutdown() - connection.connectingLock.Unlock() - } + // work around: service.shutdown() can block for a long time if it is Open()ing a new connection, putting it in a + // goroutine means we can perform this operation and let the per service shutdown in their own time or until the app exits + go func() { + connection.connectingLock.Lock() + connection.service.Shutdown() + connection.connectingLock.Unlock() + }() + } e.queue.Shutdown() }