diff --git a/CHANGELOG.md b/CHANGELOG.md index c228706e..cf5dc962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,2 +1,6 @@ +# 2.0.1 +* Add `ignoreQueryAndFragment` to `ResponseCache`. +* Rename `CacheService.ignoreQuery` to `ignoreParams`. + # 1.0.0 * First version \ No newline at end of file diff --git a/lib/src/cache.dart b/lib/src/cache.dart index 0fc21c64..059e1cb5 100644 --- a/lib/src/cache.dart +++ b/lib/src/cache.dart @@ -19,7 +19,10 @@ class ResponseCache { final Map _cache = {}; final Map _writeLocks = {}; - ResponseCache({this.timeout}); + /// If `true` (default: `false`), then caching of results will discard URI query parameters and fragments. + final bool ignoreQueryAndFragment; + + ResponseCache({this.timeout, this.ignoreQueryAndFragment: false}); /// Closes all internal write-locks, and closes the cache. Future close() async { @@ -40,9 +43,9 @@ class ResponseCache { // Check if there is a cache entry. for (var pattern in patterns) { - if (pattern.allMatches(req.uri.path).isNotEmpty && - _cache.containsKey(req.uri.path)) { - var response = _cache[req.uri.path]; + if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty && + _cache.containsKey(_getEffectivePath(req))) { + var response = _cache[_getEffectivePath(req)]; //print('timestamp ${response.timestamp} vs since ${modifiedSince}'); if (response.timestamp.compareTo(modifiedSince) <= 0) { @@ -62,6 +65,9 @@ class ResponseCache { return true; } + String _getEffectivePath(RequestContext req) => + ignoreQueryAndFragment == true ? req.uri.path : req.uri.toString(); + /// Serves content from the cache, if applicable. Future handleRequest(RequestContext req, ResponseContext res) async { if (!await ifModifiedSince(req, res)) return false; @@ -73,11 +79,11 @@ class ResponseCache { // If `if-modified-since` is present, this check has already been performed. if (req.headers.ifModifiedSince == null) { for (var pattern in patterns) { - if (pattern.allMatches(req.uri.path).isNotEmpty) { + if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty) { var now = new DateTime.now().toUtc(); - if (_cache.containsKey(req.uri.path)) { - var response = _cache[req.uri.path]; + if (_cache.containsKey(_getEffectivePath(req))) { + var response = _cache[_getEffectivePath(req)]; if (timeout != null) { // If the cache timeout has been met, don't send the cached response. @@ -108,27 +114,27 @@ class ResponseCache { // Check if there is a cache entry. for (var pattern in patterns) { - if (pattern.allMatches(req.uri.path).isNotEmpty) { + if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty) { var now = new DateTime.now().toUtc(); // Invalidate the response, if need be. - if (_cache.containsKey(req.uri.path)) { + if (_cache.containsKey(_getEffectivePath(req))) { // If there is no timeout, don't invalidate. if (timeout == null) return true; // Otherwise, don't invalidate unless the timeout has been exceeded. - var response = _cache[req.uri.path]; + var response = _cache[_getEffectivePath(req)]; if (now.difference(response.timestamp) < timeout) return true; // If the cache entry should be invalidated, then invalidate it. - purge(req.uri.path); + purge(_getEffectivePath(req)); } // Save the response. var writeLock = - _writeLocks.putIfAbsent(req.uri.path, () => new Pool(1)); + _writeLocks.putIfAbsent(_getEffectivePath(req), () => new Pool(1)); await writeLock.withResource(() { - _cache[req.uri.path] = new _CachedResponse( + _cache[_getEffectivePath(req)] = new _CachedResponse( new Map.from(res.headers), res.buffer.toBytes(), now); }); diff --git a/lib/src/cache_service.dart b/lib/src/cache_service.dart index c67d8a8e..d86c3ca3 100644 --- a/lib/src/cache_service.dart +++ b/lib/src/cache_service.dart @@ -16,7 +16,10 @@ class CacheService extends Service { /// If not provided, this defaults to a [MapService]. final Service cache; - final bool ignoreQuery; + /// If `true` (default: `false`), then result caching will discard parameters passed to service methods. + /// + /// If you want to return a cached result more-often-than-not, you may want to enable this. + final bool ignoreParams; final Duration timeout; @@ -26,7 +29,7 @@ class CacheService extends Service { CacheService( {@required this.database, @required this.cache, - this.ignoreQuery: false, + this.ignoreParams: false, this.timeout}) { assert(database != null); } @@ -47,7 +50,7 @@ class CacheService extends Service { if (timeout == null || !expired) { // Read from the cache if necessary - var queryEqual = ignoreQuery == true || + var queryEqual = ignoreParams == true || (params != null && cached.params != null && const MapEquality().equals( diff --git a/pubspec.yaml b/pubspec.yaml index f8bea6bb..632a1a38 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_cache -version: 2.0.0 +version: 2.0.1 homepage: https://github.com/angel-dart/cache description: Support for server-side caching in Angel. author: Tobe O