This commit is contained in:
Tobe O 2018-11-10 11:59:07 -05:00
parent 37abf01168
commit aea408b2f7
4 changed files with 30 additions and 17 deletions

View file

@ -1,2 +1,6 @@
# 2.0.1
* Add `ignoreQueryAndFragment` to `ResponseCache`.
* Rename `CacheService.ignoreQuery` to `ignoreParams`.
# 1.0.0
* First version

View file

@ -19,7 +19,10 @@ class ResponseCache {
final Map<String, _CachedResponse> _cache = {};
final Map<String, Pool> _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<bool> 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);
});

View file

@ -16,7 +16,10 @@ class CacheService<Id, Data> extends Service<Id, Data> {
/// If not provided, this defaults to a [MapService].
final Service<Id, Data> 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<Id, Data> extends Service<Id, Data> {
CacheService(
{@required this.database,
@required this.cache,
this.ignoreQuery: false,
this.ignoreParams: false,
this.timeout}) {
assert(database != null);
}
@ -47,7 +50,7 @@ class CacheService<Id, Data> extends Service<Id, Data> {
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(

View file

@ -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 <thosakwe@gmail.com>