LCOV - code coverage report
Current view: top level - async-1.13.3/lib/src - async_cache.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 0 24 0.0 %
Date: 2017-10-10 20:17:03 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'dart:async';
       6             : 
       7             : import 'package:async/async.dart';
       8             : 
       9             : /// Runs asynchronous functions and caches the result for a period of time.
      10             : ///
      11             : /// This class exists to cover the pattern of having potentially expensive code
      12             : /// such as file I/O, network access, or isolate computation that's unlikely to
      13             : /// change quickly run fewer times. For example:
      14             : ///
      15             : /// ```dart
      16             : /// final _usersCache = new AsyncCache<List<String>>(const Duration(hours: 1));
      17             : ///
      18             : /// /// Uses the cache if it exists, otherwise calls the closure:
      19             : /// Future<List<String>> get onlineUsers => _usersCache.fetch(() {
      20             : ///   // Actually fetch online users here.
      21             : /// });
      22             : /// ```
      23             : ///
      24             : /// This class's timing can be mocked using [`fake_async`][fake_async].
      25             : ///
      26             : /// [fake_async]: https://pub.dartlang.org/packages/fake_async
      27             : class AsyncCache<T> {
      28             :   /// How long cached values stay fresh.
      29             :   final Duration _duration;
      30             : 
      31             :   /// Cached results of a previous [fetchStream] call.
      32             :   StreamSplitter<T> _cachedStreamSplitter;
      33             : 
      34             :   /// Cached results of a previous [fetch] call.
      35             :   Future<T> _cachedValueFuture;
      36             : 
      37             :   /// Fires when the cache should be considered stale.
      38             :   Timer _stale;
      39             : 
      40             :   /// Creates a cache that invalidates after an in-flight request is complete.
      41             :   ///
      42             :   /// An ephemeral cache guarantees that a callback function will only be
      43             :   /// executed at most once concurrently. This is useful for requests for which
      44             :   /// data is updated frequently but stale data is acceptable.
      45           0 :   factory AsyncCache.ephemeral() => new AsyncCache(Duration.ZERO);
      46             : 
      47             :   /// Creates a cache that invalidates its contents after [duration] has passed.
      48             :   ///
      49             :   /// The [duration] starts counting after the Future returned by [fetch]
      50             :   /// completes, or after the Stream returned by [fetchStream] emits a done
      51             :   /// event.
      52           0 :   AsyncCache(this._duration);
      53             : 
      54             :   /// Returns a cached value from a previous call to [fetch], or runs [callback]
      55             :   /// to compute a new one.
      56             :   ///
      57             :   /// If [fetch] has been called recently enough, returns its previous return
      58             :   /// value. Otherwise, runs [callback] and returns its new return value.
      59             :   Future<T> fetch(Future<T> callback()) async {
      60           0 :     if (_cachedStreamSplitter != null) {
      61           0 :       throw new StateError('Previously used to cache via `fetchStream`');
      62             :     }
      63           0 :     if (_cachedValueFuture == null) {
      64           0 :       _cachedValueFuture = callback();
      65           0 :       await _cachedValueFuture;
      66           0 :       _startStaleTimer();
      67             :     }
      68           0 :     return _cachedValueFuture;
      69           0 :   }
      70             : 
      71             :   /// Returns a cached stream from a previous call to [fetchStream], or runs
      72             :   /// [callback] to compute a new stream.
      73             :   ///
      74             :   /// If [fetchStream] has been called recently enough, returns a copy of its
      75             :   /// previous return value. Otherwise, runs [callback] and returns its new
      76             :   /// return value.
      77             :   Stream<T> fetchStream(Stream<T> callback()) {
      78           0 :     if (_cachedValueFuture != null) {
      79           0 :       throw new StateError('Previously used to cache via `fetch`');
      80             :     }
      81           0 :     if (_cachedStreamSplitter == null) {
      82           0 :       _cachedStreamSplitter = new StreamSplitter(callback()
      83           0 :           .transform(new StreamTransformer.fromHandlers(handleDone: (sink) {
      84           0 :         _startStaleTimer();
      85           0 :         sink.close();
      86             :       })));
      87             :     }
      88           0 :     return _cachedStreamSplitter.split();
      89             :   }
      90             : 
      91             :   /// Removes any cached value.
      92             :   void invalidate() {
      93           0 :     _cachedValueFuture = null;
      94           0 :     _cachedStreamSplitter?.close();
      95           0 :     _cachedStreamSplitter = null;
      96           0 :     _stale?.cancel();
      97           0 :     _stale = null;
      98             :   }
      99             : 
     100             :   void _startStaleTimer() {
     101           0 :     _stale = new Timer(_duration, invalidate);
     102             :   }
     103             : }

Generated by: LCOV version 1.13