Makes it so we don't have to wait for all servers to be connected before fetching
This commit is contained in:
@@ -52,7 +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
|
||||
fetchCompletion(.failure(error))
|
||||
} else {
|
||||
self.connected = true
|
||||
}
|
||||
}) { (devices: [HubitatDevice]) in
|
||||
self.devices = devices
|
||||
|
||||
@@ -54,15 +54,9 @@ class ServerMultiplex
|
||||
|
||||
public func refreshDevices()
|
||||
{
|
||||
ensureConnection { (error: Error?) in
|
||||
if let error = error {
|
||||
self.handleError(error)
|
||||
} else {
|
||||
self.servers.forEach { (server: Server) in
|
||||
server.fetchDevices { (result: Result<[AnyDevice], Error>) in
|
||||
self.handleServerFetchResult(result)
|
||||
}
|
||||
}
|
||||
self.servers.forEach { (server: Server) in
|
||||
server.fetchDevices { (result: Result<[AnyDevice], Error>) in
|
||||
self.handleServerFetchResult(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,25 +64,6 @@ class ServerMultiplex
|
||||
|
||||
extension ServerMultiplex
|
||||
{
|
||||
private func ensureConnection(then: @escaping (Error?) -> Void)
|
||||
{
|
||||
let disconnectedServers = servers.filter { $0.connected == false }
|
||||
var disconnectedServerCount = disconnectedServers.count
|
||||
|
||||
if disconnectedServerCount > 0 {
|
||||
disconnectedServers.forEach { (server: Server) in
|
||||
server.connect { (error: Error?) in
|
||||
disconnectedServerCount -= 1
|
||||
if disconnectedServerCount == 0 {
|
||||
then(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
then(nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func handleServerFetchResult(_ result: Result<[AnyDevice], Error>)
|
||||
{
|
||||
switch result {
|
||||
|
||||
@@ -26,8 +26,10 @@ class WemoServer : Server
|
||||
{
|
||||
private var devices: [WemoDevice] = []
|
||||
|
||||
public var connected: Bool { get { return self.connectionStatus == .connected } }
|
||||
|
||||
fileprivate(set) var baseURL: URL
|
||||
fileprivate(set) var connected: Bool = false
|
||||
fileprivate(set) var connectionStatus: ConnectionStatus = .disconnected
|
||||
|
||||
fileprivate var _urlSession: URLSession
|
||||
fileprivate var _errorStream: StandardErrorOutputStream = StandardErrorOutputStream()
|
||||
@@ -45,15 +47,16 @@ class WemoServer : Server
|
||||
|
||||
func connect(_ completion: @escaping (Error?) -> Void)
|
||||
{
|
||||
if (!self.connected) {
|
||||
if (self.connectionStatus == .disconnected) {
|
||||
let op = ConnectOperation(baseURL: self.baseURL, session: _urlSession)
|
||||
weak var weakOp = op
|
||||
op.completionBlock = {
|
||||
guard let strongOp = weakOp else { completion(nil) ; return }
|
||||
if let error = strongOp.error {
|
||||
self._logError("Error connecting to server", error: error)
|
||||
self.connectionStatus = .disconnected
|
||||
} else {
|
||||
self.connected = true
|
||||
self.connectionStatus = .connected
|
||||
}
|
||||
|
||||
completion(strongOp.error)
|
||||
@@ -66,27 +69,34 @@ class WemoServer : Server
|
||||
|
||||
func disconnect(_ completion: (Error?) -> Void)
|
||||
{
|
||||
self.connected = false
|
||||
self.connectionStatus = .disconnected
|
||||
completion(nil)
|
||||
}
|
||||
|
||||
func fetchDevices(_ completion: @escaping (Result<[AnyDevice], Error>) -> Void)
|
||||
{
|
||||
if (self.connected) {
|
||||
let op = FetchDevicesOperation(baseURL: self.baseURL, session: _urlSession)
|
||||
weak var weakOp = op
|
||||
op.completionBlock = {
|
||||
guard let strongOp = weakOp else { return }
|
||||
if let error = strongOp.error {
|
||||
self._logError("Error fetching devices", error: error)
|
||||
completion(.failure(error))
|
||||
} else {
|
||||
self.devices = strongOp.devices
|
||||
}
|
||||
|
||||
let op = FetchDevicesOperation(baseURL: self.baseURL, session: _urlSession)
|
||||
weak var weakOp = op
|
||||
op.completionBlock = {
|
||||
guard let strongOp = weakOp else { return }
|
||||
if let error = strongOp.error {
|
||||
self._logError("Error fetching devices", error: error)
|
||||
completion(.failure(error))
|
||||
} else {
|
||||
self.devices = strongOp.devices
|
||||
completion(.success(self.devices.map { AnyDevice($0) }))
|
||||
}
|
||||
|
||||
self.devices = strongOp.devices
|
||||
completion(.success(self.devices.map { AnyDevice($0) }))
|
||||
}
|
||||
|
||||
if self.connectionStatus == .disconnected {
|
||||
connect { error in
|
||||
if error == nil {
|
||||
self._operationQueue.addOperation(op)
|
||||
}
|
||||
}
|
||||
} else if self.connectionStatus == .connected {
|
||||
_operationQueue.addOperation(op)
|
||||
} else {
|
||||
completion(.failure(ConnectionError.serverUnavailable))
|
||||
|
||||
Reference in New Issue
Block a user