Fixes issue where connectivity issues can lead to persistent "Offline" status in UI

This fixes the problem where either internet connectivity issues on the device or intermittant
server issues can cause a persistent "OFFLINE" indicator even though that is not the case.

This requires the server protocol to be more granular about what their connection status is,
and adds a new signal from the multiplexer to the MainViewController allowing it to notify the
delegate that an acknowledgement was heard from one of the servers, allowing the main view
controller to update its UI according to whatever status best represents the group of servers
as a whole.

Testing
- This can be tested by using the network link conditioner to simulate connection issues
  *after* the control panel has connected to all servers in the multiplex.
- Tested losing internet connection and regaining internet connection
- Tested starting off with no connection and regaining connection later
This commit is contained in:
2020-07-04 19:43:50 -07:00
parent ee29602640
commit d1da677932
5 changed files with 55 additions and 31 deletions
+5 -5
View File
@@ -16,7 +16,7 @@ public enum HubitatServerError : Error
public class HubitatServer : Server
{
var connected: Bool = false
var connectionStatus: ConnectionStatus = .disconnected
public fileprivate(set) var devices: [HubitatDevice] = []
@@ -33,13 +33,13 @@ public class HubitatServer : Server
func connect(_ completion: @escaping (Error?) -> Void)
{
// RESTful, assume we're connected unless we get an error
self.connected = true
connectionStatus = .connected
completion(nil)
}
func disconnect(_ completion: (Error?) -> Void)
{
self.connected = false
connectionStatus = .disconnected
}
func fetchDevices(_ fetchCompletion: @escaping (Result<[AnyDevice], Error>) -> Void)
@@ -52,10 +52,10 @@ public class HubitatServer : Server
.decode(type: [HubitatDevice].self, decoder: JSONDecoder())
.sink(receiveCompletion: { completion in
if case let Subscribers.Completion.failure(error) = completion {
self.connected = false
self.connectionStatus = .error
fetchCompletion(.failure(error))
} else {
self.connected = true
self.connectionStatus = .connected
}
}) { (devices: [HubitatDevice]) in
self.devices = devices