         guard let end = cache.endHandle(for: characteristic)
             else { fatalError("Could not retrieve handles") }
         
-        let operation = DescriptorDiscoveryOperation(start: start, end: end, completion: completion)
+        let operation = DescriptorDiscoveryOperation(start: start, end: end) { [unowned self] (response) in
+            
+            // update cache
+            switch response {
+            case .error:
+                break
+            case let .value(value):
+                self.cache.update(value, for: characteristic)
+            }
+            
+            // call completion
+            completion(response)
+        }
         
         discoverDescriptors(operation: operation)
     }

        
        fileprivate(set) var characteristic: GATTClient.Characteristic
        
        private(set) var descriptors: [BluetoothUUID: GATTClient.Descriptor]
        
        mutating func update(_ newValue: [GATTClient.Descriptor]) {
            

    
    internal struct Cache {
        
        fileprivate(set) var services = [BluetoothUUID: CachedService]()
        
        mutating func update(_ newValue: [Service], isCompleteSet: Bool = true) {
            
